Browse Source

增加禁言相关流程功能和UI样式

Pq 10 months ago
parent
commit
046ea4d3f2
46 changed files with 2439 additions and 13 deletions
  1. 1 0
      BaseLibrary/src/main/java/com/cooleshow/base/router/RouterPath.kt
  2. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_box_checked2.png
  3. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_box_normal2.png
  4. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_close_bg.png
  5. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_close_black.png
  6. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_box_checked2.png
  7. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_box_normal2.png
  8. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_close_bg.png
  9. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_close_black.png
  10. 8 0
      BaseLibrary/src/main/res/drawable/bg_white_top_20dp.xml
  11. 8 0
      BaseLibrary/src/main/res/drawable/common_check_selector2.xml
  12. 5 0
      BaseLibrary/src/main/res/drawable/shape_2dc7aa_18dp.xml
  13. 5 0
      BaseLibrary/src/main/res/drawable/shape_2dc7aa_4dp.xml
  14. 6 0
      chatModule/src/main/AndroidManifest.xml
  15. 26 0
      chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMemberSelectAvatarListAdapter.java
  16. 30 0
      chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMemberSelectListDialogAdapter.java
  17. 47 0
      chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMuteManagerPagerAdapter.java
  18. 129 0
      chatModule/src/main/java/com/cooleshow/chatmodule/adapter/MuteMemberListAdapter.java
  19. 6 0
      chatModule/src/main/java/com/cooleshow/chatmodule/api/IMApi.java
  20. 14 1
      chatModule/src/main/java/com/cooleshow/chatmodule/bean/GroupMemberBean.java
  21. 9 0
      chatModule/src/main/java/com/cooleshow/chatmodule/bean/IMGroupInfo.java
  22. 9 0
      chatModule/src/main/java/com/cooleshow/chatmodule/constants/Constants.java
  23. 16 0
      chatModule/src/main/java/com/cooleshow/chatmodule/constants/GroupRoleType.java
  24. 2 0
      chatModule/src/main/java/com/cooleshow/chatmodule/contract/ChatGroupSettingContract.java
  25. 26 0
      chatModule/src/main/java/com/cooleshow/chatmodule/contract/MuteMemberContract.java
  26. 5 0
      chatModule/src/main/java/com/cooleshow/chatmodule/manager/IMCenter.java
  27. 21 0
      chatModule/src/main/java/com/cooleshow/chatmodule/presenter/ChatGroupSettingPresenter.java
  28. 88 0
      chatModule/src/main/java/com/cooleshow/chatmodule/presenter/MuteMemberPresenter.java
  29. 87 12
      chatModule/src/main/java/com/cooleshow/chatmodule/ui/ChatGroupSettingActivity.java
  30. 267 0
      chatModule/src/main/java/com/cooleshow/chatmodule/ui/HasMuteMemberFragment.java
  31. 127 0
      chatModule/src/main/java/com/cooleshow/chatmodule/ui/MuteMemberManagerActivity.java
  32. 268 0
      chatModule/src/main/java/com/cooleshow/chatmodule/ui/NoMuteMemberFragment.java
  33. 296 0
      chatModule/src/main/java/com/cooleshow/chatmodule/ui/TUIChatGroupActivityV2.java
  34. 142 0
      chatModule/src/main/java/com/cooleshow/chatmodule/widget/MemberSelectListDialog.java
  35. BIN
      chatModule/src/main/res/drawable-xhdpi/icon_chat_mute_tip.png
  36. BIN
      chatModule/src/main/res/drawable-xxhdpi/icon_chat_mute_tip.png
  37. 54 0
      chatModule/src/main/res/layout/ac_group_mute_manager_layout.xml
  38. 58 0
      chatModule/src/main/res/layout/dialog_group_select_list_layout.xml
  39. 215 0
      chatModule/src/main/res/layout/fragment_has_mute_member_layout.xml
  40. 214 0
      chatModule/src/main/res/layout/fragment_no_mute_member_layout.xml
  41. 44 0
      chatModule/src/main/res/layout/item_group_select_list_dialog_layout.xml
  42. 112 0
      chatModule/src/main/res/layout/item_mute_member_list_layout.xml
  43. 11 0
      chatModule/src/main/res/layout/item_student_select_avatar_layout.xml
  44. 33 0
      chatModule/src/main/res/layout/tc_activity_chat_group_setting.xml
  45. 18 0
      chatModule/src/main/res/layout/view_group_manager_tab_layout.xml
  46. 32 0
      chatModule/src/main/res/layout/view_mute_input_layout.xml

+ 1 - 0
BaseLibrary/src/main/java/com/cooleshow/base/router/RouterPath.kt

@@ -190,6 +190,7 @@ object RouterPath {
             const val CHAT_GROUP_MEMBER = "/rong/imkit/activity/GroupMemberActivity"
             const val CHAT_GROUP_JOIN_APPLY = "/rong/imkit/activity/JoinGroupApplyActivity"
             const val CHAT_SELECT_CONTACT = "/rong/imkit/activity/SelectContactActivity"
+            const val CHAT_MUTE_MANAGER = "/rong/imkit/activity/MuteMemberManagerActivity"
         }
     }
 

BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_box_checked2.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_box_normal2.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_close_bg.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_close_black.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_box_checked2.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_box_normal2.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_close_bg.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_close_black.png


+ 8 - 0
BaseLibrary/src/main/res/drawable/bg_white_top_20dp.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@color/white" />
+    <corners
+        android:topLeftRadius="@dimen/dp_20"
+        android:topRightRadius="@dimen/dp_20" />
+</shape>

+ 8 - 0
BaseLibrary/src/main/res/drawable/common_check_selector2.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector
+  xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:drawable="@drawable/icon_box_checked2" />
+    <item android:state_checked="false" android:drawable="@drawable/icon_box_normal2" />
+    <item android:state_checked="true" android:drawable="@drawable/icon_box_checked2" />
+    <item android:drawable="@drawable/icon_box_normal2" />
+</selector>

+ 5 - 0
BaseLibrary/src/main/res/drawable/shape_2dc7aa_18dp.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/color_2dc7aa" />
+    <corners android:radius="18dp" />
+</shape>

+ 5 - 0
BaseLibrary/src/main/res/drawable/shape_2dc7aa_4dp.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/color_2dc7aa"/>
+    <corners android:radius="4dp"/>
+</shape>

+ 6 - 0
chatModule/src/main/AndroidManifest.xml

@@ -74,6 +74,12 @@
             android:windowSoftInputMode="adjustPan"
             android:screenOrientation="portrait" />
 
+        <activity
+            android:name=".ui.MuteMemberManagerActivity"
+            android:windowSoftInputMode="adjustPan"
+            android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout"
+            android:screenOrientation="portrait" />
+
         <provider
             android:name=".widget.CustomChatGroupTopRightIconExtension"
             android:authorities="${applicationId}.TUIGroup.ClassicUI.Init"

+ 26 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMemberSelectAvatarListAdapter.java

@@ -0,0 +1,26 @@
+package com.cooleshow.chatmodule.adapter;
+
+import android.widget.ImageView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2024/2/20.
+ */
+public class GroupMemberSelectAvatarListAdapter extends BaseQuickAdapter<GroupMemberBean, BaseViewHolder> {
+    public GroupMemberSelectAvatarListAdapter() {
+        super(R.layout.item_student_select_avatar_layout);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, GroupMemberBean bean) {
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+        GlideUtils.INSTANCE.loadImage(getContext(), bean.getAvatar(), iv_avatar, com.cooleshow.base.R.drawable.icon_default_head);
+    }
+}

+ 30 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMemberSelectListDialogAdapter.java

@@ -0,0 +1,30 @@
+package com.cooleshow.chatmodule.adapter;
+
+import android.widget.ImageView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2023/1/2.
+ */
+public class GroupMemberSelectListDialogAdapter extends BaseQuickAdapter<GroupMemberBean, BaseViewHolder> {
+
+    public GroupMemberSelectListDialogAdapter() {
+        super(R.layout.item_group_select_list_dialog_layout);
+        addChildClickViewIds(R.id.iv_del);
+    }
+
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, GroupMemberBean bean) {
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+        GlideUtils.INSTANCE.loadImage(getContext(), bean.getAvatar(), iv_avatar, com.cooleshow.base.R.drawable.icon_default_head);
+        holder.setText(R.id.tv_name, bean.getNickname());
+    }
+}

+ 47 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/adapter/GroupMuteManagerPagerAdapter.java

@@ -0,0 +1,47 @@
+package com.cooleshow.chatmodule.adapter;
+
+import java.util.ArrayList;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+
+/**
+ * Author by pq, Date on 2022/5/6.
+ */
+public class GroupMuteManagerPagerAdapter extends FragmentStateAdapter {
+    private ArrayList<Fragment> mFragments;
+
+    public GroupMuteManagerPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
+        super(fragmentActivity);
+    }
+
+
+    public void setData(ArrayList<Fragment> fragments) {
+        this.mFragments = fragments;
+        notifyDataSetChanged();
+    }
+
+    @NonNull
+    @Override
+    public Fragment createFragment(int position) {
+        return mFragments.get(position);
+    }
+
+    @Override
+    public int getItemCount() {
+        return mFragments != null ? mFragments.size() : 0;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        Fragment fragment = mFragments.get(position);
+        return fragment != null ? fragment.hashCode() : super.getItemId(position);
+    }
+
+    @Override
+    public boolean containsItem(long itemId) {
+        return super.containsItem(itemId);
+    }
+}

+ 129 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/adapter/MuteMemberListAdapter.java

@@ -0,0 +1,129 @@
+package com.cooleshow.chatmodule.adapter;
+
+import android.graphics.Typeface;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.base.utils.SizeUtils;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2022/5/7.
+ */
+public class MuteMemberListAdapter extends BaseQuickAdapter<GroupMemberBean, BaseViewHolder> {
+    private ArrayList<GroupMemberBean> selectDatas;
+
+    public MuteMemberListAdapter() {
+        super(R.layout.item_mute_member_list_layout);
+        selectDatas = new ArrayList<>();
+    }
+
+
+    public void selectAll(boolean isSelectAll) {
+        if (isSelectAll) {
+            selectCurrentAll();
+            notifyDataSetChanged();
+        } else {
+            cancelSelectCurrentAll();
+            notifyDataSetChanged();
+        }
+    }
+
+    private void cancelSelectCurrentAll() {
+        clearSelect();
+    }
+
+    public void clearSelect() {
+        if (selectDatas != null) {
+            selectDatas.clear();
+        }
+    }
+
+    private void selectCurrentAll() {
+        for (int i = 0; i < getData().size(); i++) {
+            GroupMemberBean rowsBean = getData().get(i);
+            if (isContain(rowsBean) == -1) {
+                selectDatas.add(rowsBean);
+            }
+        }
+    }
+
+    private int isContain(GroupMemberBean rowsBean) {
+        for (int i = 0; i < selectDatas.size(); i++) {
+            GroupMemberBean s = selectDatas.get(i);
+            if (TextUtils.equals(s.getUserId(), rowsBean.getUserId())) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public void setSelect(GroupMemberBean bean) {
+        int pos = isContain(bean);
+        if (pos != -1) {
+            selectDatas.remove(pos);
+        } else {
+            selectDatas.add(bean);
+        }
+        notifyDataSetChanged();
+    }
+
+    public void setSelect(List<GroupMemberBean> bean) {
+        selectDatas.clear();
+        selectDatas.addAll(bean);
+        notifyDataSetChanged();
+    }
+
+    public ArrayList<GroupMemberBean> getSelectList() {
+        return selectDatas;
+    }
+
+    public boolean isSelectCurrentAllData() {
+        if (selectDatas == null || selectDatas.size() == 0) {
+            return false;
+        }
+        List<GroupMemberBean> data = getData();
+        for (int i = 0; i < data.size(); i++) {
+            GroupMemberBean rowsBean = data.get(i);
+            int contain = isContain(rowsBean);
+            if (contain == -1) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, GroupMemberBean rowsBean) {
+        TextView tv_name = holder.getView(R.id.tv_name);
+        tv_name.setTypeface(Typeface.DEFAULT);
+        holder.setText(R.id.tv_name, rowsBean.getNickname());
+        ImageView iv_icon = holder.getView(R.id.iv_icon);
+        GlideUtils.INSTANCE.loadImage(getContext(), rowsBean.getAvatar(), iv_icon);
+
+        ImageView iv_check = holder.getView(R.id.iv_check);
+        boolean isCheck = isContain(rowsBean) != -1;
+        iv_check.setImageResource(isCheck ? com.cooleshow.base.R.drawable.icon_box_checked2 : com.cooleshow.base.R.drawable.icon_box_normal2);
+
+        View view = holder.getView(R.id.root_view);
+        RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
+        if (holder.getLayoutPosition() == getData().size() - 1) {
+            layoutParams.setMargins(0, 0, 0, SizeUtils.dp2px(10));
+        } else {
+            layoutParams.setMargins(0, 0, 0, 0);
+        }
+        view.setLayoutParams(layoutParams);
+    }
+}

+ 6 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/api/IMApi.java

@@ -170,4 +170,10 @@ public interface IMApi {
      */
     @POST(TEACHER_GROUP + "imGroup/update")
     Observable<BaseResponse<Object>> updateGroupInfo(@Body RequestBody body);
+
+    @POST("{group_name}" + "/imGroupMember/groupMute")
+    Observable<BaseResponse<Object>> groupMemberMute(@Body RequestBody body,@Path("group_name")String group_name);
+
+    @POST("{group_name}" + "/imGroup/muteAll")
+    Observable<BaseResponse<Object>> groupMute(@Body RequestBody body,@Path("group_name")String group_name);
 }

+ 14 - 1
chatModule/src/main/java/com/cooleshow/chatmodule/bean/GroupMemberBean.java

@@ -41,6 +41,16 @@ public class GroupMemberBean extends BaseIndexPinyinBean implements Serializable
     private String imUserId;
     private int itemType;
 
+    private String groupRoleType;
+
+    public String getGroupRoleType() {
+        return groupRoleType;
+    }
+
+    public void setGroupRoleType(String groupRoleType) {
+        this.groupRoleType = groupRoleType;
+    }
+
     public String getAvatar() {
         return avatar;
     }
@@ -154,6 +164,7 @@ public class GroupMemberBean extends BaseIndexPinyinBean implements Serializable
         dest.writeString(this.userId);
         dest.writeString(this.imUserId);
         dest.writeInt(this.itemType);
+        dest.writeString(this.groupRoleType);
     }
 
     public void readFromParcel(Parcel source) {
@@ -168,6 +179,7 @@ public class GroupMemberBean extends BaseIndexPinyinBean implements Serializable
         this.userId = source.readString();
         this.imUserId = source.readString();
         this.itemType = source.readInt();
+        this.groupRoleType = source.readString();
     }
 
     public GroupMemberBean() {
@@ -185,9 +197,10 @@ public class GroupMemberBean extends BaseIndexPinyinBean implements Serializable
         this.userId = in.readString();
         this.imUserId = in.readString();
         this.itemType = in.readInt();
+        this.groupRoleType = in.readString();
     }
 
-    public static final Parcelable.Creator<GroupMemberBean> CREATOR = new Parcelable.Creator<GroupMemberBean>() {
+    public static final Creator<GroupMemberBean> CREATOR = new Creator<GroupMemberBean>() {
         @Override
         public GroupMemberBean createFromParcel(Parcel source) {
             return new GroupMemberBean(source);

+ 9 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/bean/IMGroupInfo.java

@@ -37,6 +37,15 @@ public class IMGroupInfo {
     private String updateTime;
     private String createBy;
     private String createTime;
+    private String configJson;
+
+    public String getConfigJson() {
+        return configJson;
+    }
+
+    public void setConfigJson(String configJson) {
+        this.configJson = configJson;
+    }
 
     public String getId() {
         return id;

+ 9 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/constants/Constants.java

@@ -0,0 +1,9 @@
+package com.cooleshow.chatmodule.constants;
+
+/**
+ * Author by pq, Date on 2024/5/20.
+ */
+public class Constants {
+    public static final String TARGET_ID_KEY = "targetId";
+    public static final long MAX_MUTE_TIME = -1;
+}

+ 16 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/constants/GroupRoleType.java

@@ -0,0 +1,16 @@
+package com.cooleshow.chatmodule.constants;
+
+/**
+ * Author by pq, Date on 2023/8/23.
+ */
+public enum GroupRoleType {
+    Owner("群主"),
+    Admin("管理员"),
+    Member("群成员");
+
+    public String value;
+
+    GroupRoleType(String value) {
+        this.value = value;
+    }
+}

+ 2 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/contract/ChatGroupSettingContract.java

@@ -36,6 +36,8 @@ public interface ChatGroupSettingContract {
 
         void getGroupInfoError();
 
+        void changeMuteModeSuccess();
+
     }
 
     interface Presenter {

+ 26 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/contract/MuteMemberContract.java

@@ -0,0 +1,26 @@
+package com.cooleshow.chatmodule.contract;
+
+import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+
+import java.util.List;
+
+/**
+ * 创建日期:2022/6/11 18:10
+ *
+ * @author Ryan
+ * 类说明:
+ */
+public interface MuteMemberContract {
+    interface MuteMemberView extends BaseView {
+
+        void onGroupUsers(List<GroupMemberBean> data);
+
+        void getListError();
+
+        void changeMuteStatusSuccess();
+    }
+
+    interface Presenter {
+    }
+}

+ 5 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/manager/IMCenter.java

@@ -177,4 +177,9 @@ public class IMCenter {
     public void quitGroup(String groupId, V2TIMCallback callBack){
         V2TIMManager.getInstance().quitGroup(groupId,callBack);
     }
+
+    public long getServerTime(){
+        long serverTime = V2TIMManager.getInstance().getServerTime();
+        return serverTime;
+    }
 }

+ 21 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/presenter/ChatGroupSettingPresenter.java

@@ -254,4 +254,25 @@ public class ChatGroupSettingPresenter extends BasePresenter<ChatGroupSettingCon
             }
         });
     }
+
+    public void changeGroupMuteStatus(String groupId, boolean isMuteAll) {
+        if (getView() != null) {
+            getView().showLoading();
+        }
+        JSONObject jsonObject = new JSONObject();
+        try {
+            jsonObject.put("groupId", groupId);
+            jsonObject.put("muteAll", isMuteAll);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(IMApi.class).groupMute(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString()), BaseConstant.CLIENT_API_GROUP_NAME), new BaseObserver<Object>(getView()) {
+            @Override
+            protected void onSuccess(Object data) {
+                if (getView() != null) {
+                    getView().changeMuteModeSuccess();
+                }
+            }
+        });
+    }
 }

+ 88 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/presenter/MuteMemberPresenter.java

@@ -0,0 +1,88 @@
+package com.cooleshow.chatmodule.presenter;
+
+import com.cooleshow.base.common.BaseConstant;
+import com.cooleshow.base.presenter.BasePresenter;
+import com.cooleshow.base.rx.BaseObserver;
+import com.cooleshow.base.utils.RequestBodyUtil;
+import com.cooleshow.chatmodule.api.IMApi;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+import com.cooleshow.chatmodule.constants.Constants;
+import com.cooleshow.chatmodule.constants.GroupRoleType;
+import com.cooleshow.chatmodule.contract.MuteMemberContract;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 创建日期:2022/6/11 18:09
+ *
+ * @author Ryan
+ * 类说明:
+ */
+public class MuteMemberPresenter extends BasePresenter<MuteMemberContract.MuteMemberView> implements MuteMemberContract.Presenter {
+
+    public void queryGroupMembers(String groupId, String keyword, boolean isMute) {
+
+        JSONObject jsonObject = new JSONObject();
+        JSONArray jsonArray =new JSONArray();
+        try {
+            jsonObject.put("groupId", groupId);
+            jsonObject.put("groupMute", isMute);
+            jsonObject.put("keyword", keyword);
+            jsonArray.put(GroupRoleType.Member);
+            jsonObject.put("groupRoleTypes", jsonArray);
+            jsonObject.put("rows", Integer.MAX_VALUE);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(IMApi.class).queryGroupAllMembers(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString()),BaseConstant.CLIENT_API_GROUP_NAME), new BaseObserver<List<GroupMemberBean>>(getView()) {
+            @Override
+            protected void onSuccess(List<GroupMemberBean> data) {
+                if (getView() != null) {
+                    getView().onGroupUsers(data);
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+                if (getView() != null) {
+                    getView().getListError();
+                }
+            }
+        });
+    }
+
+
+    public void changeGroupMuteStatus(String groupId, ArrayList<String> userIds, boolean isMute) {
+
+        JSONObject jsonObject = new JSONObject();
+        try {
+
+            jsonObject.put("groupId", groupId);
+            jsonObject.put("muteTime", Constants.MAX_MUTE_TIME);
+            jsonObject.put("groupMute", isMute);
+            JSONArray jsonArray = new JSONArray(userIds);
+            jsonObject.put("userIds", jsonArray);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(IMApi.class).groupMemberMute(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString()), BaseConstant.CLIENT_API_GROUP_NAME), new BaseObserver<Object>(getView()) {
+            @Override
+            protected void onSuccess(Object data) {
+                if (getView() != null) {
+                    getView().changeMuteStatusSuccess();
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+            }
+        });
+    }
+}

+ 87 - 12
chatModule/src/main/java/com/cooleshow/chatmodule/ui/ChatGroupSettingActivity.java

@@ -17,11 +17,13 @@ import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.listener.OnItemClickListener;
 import com.cooleshow.base.bean.StudentPageListBean;
 import com.cooleshow.base.common.BaseApplication;
+import com.cooleshow.base.common.BaseConstant;
 import com.cooleshow.base.constanst.StyleConfig;
 import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseMVPActivity;
 import com.cooleshow.base.utils.GlideUtils;
 import com.cooleshow.base.utils.JumpUtils;
+import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.LogUtils;
 import com.cooleshow.base.utils.ToastUtil;
 import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
@@ -32,6 +34,8 @@ import com.cooleshow.chatmodule.adapter.GroupSettingMemberAdapter;
 import com.cooleshow.chatmodule.bean.GroupApplyBean;
 import com.cooleshow.chatmodule.bean.GroupMemberBean;
 import com.cooleshow.chatmodule.bean.IMGroupInfo;
+import com.cooleshow.chatmodule.constants.Constants;
+import com.cooleshow.chatmodule.constants.GroupRoleType;
 import com.cooleshow.chatmodule.constants.TCChatRouterPath;
 import com.cooleshow.chatmodule.contract.ChatGroupSettingContract;
 import com.cooleshow.chatmodule.databinding.TcActivityChatGroupSettingBinding;
@@ -43,6 +47,9 @@ import com.cooleshow.usercenter.helper.UserHelper;
 import com.tencent.qcloud.tuicore.TUICore;
 import com.tencent.qcloud.tuikit.tuigroup.bean.GroupInfo;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
@@ -71,6 +78,20 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
 
     private ArrayList<GroupMemberBean> allMemberList;
 
+    private String currentImUserId;
+
+    private ImageView iv_portrait;
+    private TextView tv_group_name;
+    private TextView tv_class_num;
+    private TextView tv_group_member_list;
+    private RecyclerView recyclerView;
+    private TextView tv_group_apply_count;
+    private TextView tv_group_name_remarks;
+    private CheckBox cb_message;
+    GroupSettingMemberAdapter mAdapter;
+    private GroupInfo mGroupInfo;
+    private GroupRoleType currentUserGroupType = GroupRoleType.Member;
+
     @Override
     public void onClick(View view) {
         if (view.getId() == R.id.ll_history_message) {
@@ -114,6 +135,11 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
                 //发消息
                 showQuitConfirmDialog();
             }
+        } else if (view.getId() == R.id.tv_mute_member_manager) {
+            ARouter.getInstance().build(RouterPath.ChatCenter.CHAT_MUTE_MANAGER)
+                    .withString(Constants.TARGET_ID_KEY, targetId)
+                    .navigation();
+            return;
         }
 
     }
@@ -171,17 +197,6 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
         });
     }
 
-    private ImageView iv_portrait;
-    private TextView tv_group_name;
-    private TextView tv_class_num;
-    private TextView tv_group_member_list;
-    private RecyclerView recyclerView;
-    private TextView tv_group_apply_count;
-    private TextView tv_group_name_remarks;
-    private CheckBox cb_message;
-    GroupSettingMemberAdapter mAdapter;
-    private GroupInfo mGroupInfo;
-
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -209,6 +224,8 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
         viewBinding.tvNotice.setOnClickListener(this);
         viewBinding.tvFeedback.setOnClickListener(this);
         viewBinding.btnConfirm.setOnClickListener(this);
+        viewBinding.tvMuteMemberManager.setOnClickListener(this);
+
         IMThemManager.getInstance().setCheckButtonDrawable(viewBinding.cbMessage);
         IMThemManager.getInstance().setMainButtonStyles(viewBinding.btnConfirm);
 
@@ -253,6 +270,7 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
             finish();
             return;
         }
+        currentImUserId = UserHelper.getImUserId();
         presenter.loadGroup(targetId);
 //        presenter.conversationGet(Conversation.ConversationType.GROUP, targetId);
 
@@ -270,6 +288,15 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
             }
         });
 
+        viewBinding.cbMute.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (buttonView.isPressed()) {
+                    presenter.changeGroupMuteStatus(targetId, isChecked);
+                }
+            }
+        });
+
     }
 
     @Override
@@ -319,7 +346,7 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
                 }
             }
             tv_group_member_list.setText("查看" + result.size() + "名群成员");
-
+            findGroupRole(result);
             int countLimit = isCanAddMember ? MAX_SHOW_GROUP_MEMBER_COUNT - 1 : MAX_SHOW_GROUP_MEMBER_COUNT;
             ArrayList<GroupMemberBean> list = new ArrayList();
             for (int i = 0; i < result.size(); i++) {
@@ -337,6 +364,31 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
         }
     }
 
+    private void findGroupRole(List<GroupMemberBean> list) {
+        if (list == null || list.size() == 0) {
+            return;
+        }
+        for (int i = 0; i < list.size(); i++) {
+            GroupMemberBean rowsBean = list.get(i);
+            if (TextUtils.equals(rowsBean.getImUserId(), currentImUserId)) {
+                try {
+                    currentUserGroupType = GroupRoleType.valueOf(rowsBean.getGroupRoleType());
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    currentUserGroupType = GroupRoleType.Member;
+                }
+                break;
+            }
+        }
+        LOG.i("currentUserGroupType:" + currentUserGroupType.name());
+//        viewBinding.llTransferGroupOwner.setVisibility(currentUserGroupType == GroupRoleType.Owner ? View.VISIBLE : View.GONE);
+        if(!BaseConstant.isStudentClient()){
+            boolean isCanManagerGroup = currentUserGroupType == GroupRoleType.Owner || currentUserGroupType == GroupRoleType.Admin;
+            viewBinding.cbMute.setVisibility(isCanManagerGroup ? View.VISIBLE : View.GONE);
+            viewBinding.tvMuteMemberManager.setVisibility(isCanManagerGroup ? View.VISIBLE : View.GONE);
+        }
+    }
+
     @Override
     public void onQueryGroupDetail(IMGroupInfo data) {
         if (null != data) {
@@ -354,6 +406,20 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
             tv_group_name.setText(data.getName());
             tv_group_name_remarks.setText(data.getName());
 
+            //群禁言状态
+            if (!TextUtils.isEmpty(data.getConfigJson())) {
+                try {
+                    JSONObject jsonObject = new JSONObject(data.getConfigJson());
+                    boolean mute = jsonObject.optBoolean("mute", false);
+                    viewBinding.cbMute.setChecked(mute);
+                } catch (JSONException e) {
+                    viewBinding.cbMute.setChecked(false);
+                    e.printStackTrace();
+                }
+            } else {
+                viewBinding.cbMute.setChecked(false);
+            }
+
             checkTeacherCanAddMember(data.getType());
 
             presenter.queryGroupMembers(targetId);
@@ -422,6 +488,15 @@ public class ChatGroupSettingActivity extends BaseMVPActivity<TcActivityChatGrou
     }
 
     @Override
+    public void changeMuteModeSuccess() {
+        if (!checkActivityExist()) {
+            return;
+        }
+        ToastUtil.getInstance().showShort("设置成功");
+        presenter.queryGroupDetail(targetId);
+    }
+
+    @Override
     public void addGroupMemberSuccess(Object data) {
         if (!checkActivityExist()) {
             return;

+ 267 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/ui/HasMuteMemberFragment.java

@@ -0,0 +1,267 @@
+package com.cooleshow.chatmodule.ui;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.CompoundButton;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.KeyboardUtils;
+import com.cooleshow.base.utils.SizeUtils;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.widgets.CustomSuspensionDecoration;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.adapter.GroupMemberSelectAvatarListAdapter;
+import com.cooleshow.chatmodule.adapter.MuteMemberListAdapter;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+import com.cooleshow.chatmodule.constants.Constants;
+import com.cooleshow.chatmodule.contract.MuteMemberContract;
+import com.cooleshow.chatmodule.databinding.FragmentHasMuteMemberLayoutBinding;
+import com.cooleshow.chatmodule.presenter.MuteMemberPresenter;
+import com.cooleshow.chatmodule.widget.MemberSelectListDialog;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2024/5/20.
+ */
+public class HasMuteMemberFragment extends BaseMVPFragment<FragmentHasMuteMemberLayoutBinding, MuteMemberPresenter> implements MuteMemberContract.MuteMemberView, View.OnClickListener {
+
+    private MuteMemberListAdapter mAdapter;
+    private EmptyViewLayout mEmptyViewLayout;
+    private CustomSuspensionDecoration mDecoration;
+
+    private List<GroupMemberBean> mDatas = new ArrayList<>();
+
+    private String groupId;
+    private String keywords;
+    private GroupMemberSelectAvatarListAdapter mAvatarListAdapter;
+    private MemberSelectListDialog mSelectListDialog;
+
+    public static HasMuteMemberFragment create(String groupId) {
+        Bundle bundle = new Bundle();
+        bundle.putString(Constants.TARGET_ID_KEY, groupId);
+        HasMuteMemberFragment hasMuteMemberFragment = new HasMuteMemberFragment();
+        hasMuteMemberFragment.setArguments(bundle);
+        return hasMuteMemberFragment;
+    }
+
+    @Override
+    protected void initView(View rootView) {
+
+    }
+
+    @Override
+    protected void initData() {
+        if (getArguments() != null) {
+            groupId = getArguments().getString(Constants.TARGET_ID_KEY, "");
+        }
+        mAdapter = new MuteMemberListAdapter();
+        setEmptyView();
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
+        mViewBinding.recyclerView.setLayoutManager(layoutManager);
+        mDecoration = new CustomSuspensionDecoration(getContext(), mDatas);
+        mDecoration.setColorTitleBg(Color.TRANSPARENT);
+        mDecoration.setmTitleHeight(SizeUtils.dp2px(30));
+        mViewBinding.recyclerView.addItemDecoration(mDecoration);
+        mViewBinding.livLetters.setmPressedShowTextView(mViewBinding.tvHint)//设置HintTextView
+                .setNeedRealIndex(false)//设置需要真实的索引
+                .setmLayoutManager(layoutManager);//设置RecyclerView的LayoutManager
+        mViewBinding.recyclerView.setAdapter(mAdapter);
+
+
+        mAvatarListAdapter = new GroupMemberSelectAvatarListAdapter();
+        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
+        mViewBinding.recyclerViewSelectAvatar.setLayoutManager(linearLayoutManager);
+        mViewBinding.recyclerViewSelectAvatar.setAdapter(mAvatarListAdapter);
+
+        initListener();
+
+    }
+
+    private void getData() {
+        if (TextUtils.isEmpty(groupId)) {
+            return;
+        }
+        presenter.queryGroupMembers(groupId, keywords, true);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getData();
+    }
+
+    private void initListener() {
+        mViewBinding.tvSearch.setOnClickListener(this);
+        mViewBinding.tvSure.setOnClickListener(this);
+        mViewBinding.cbAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (mAdapter != null && buttonView.isPressed()) {
+                    mAdapter.selectAll(isChecked);
+                    checkSelectAllStatus();
+                }
+            }
+        });
+        mAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                if (position < mAdapter.getData().size()) {
+                    GroupMemberBean rowsBean = mAdapter.getData().get(position);
+                    mAdapter.setSelect(rowsBean);
+                    checkSelectAllStatus();
+                }
+            }
+        });
+        mViewBinding.refreshLayout.setOnRefreshListener(new OnRefreshListener() {
+            @Override
+            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+                getData();
+            }
+        });
+
+        mAvatarListAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                showSelectListDialog();
+            }
+        });
+    }
+
+    private void checkSelectAllStatus() {
+        int selectSize = mAdapter.getSelectList().size();
+        mAvatarListAdapter.setList(mAdapter.getSelectList());
+        boolean selectCurrentAllData = mAdapter.isSelectCurrentAllData();
+        mViewBinding.tvSelectTip.setText(String.format(Locale.getDefault(), "(已选择%d):", selectSize));
+        mViewBinding.cbAll.setChecked(selectCurrentAllData);
+    }
+
+
+    private void setEmptyView() {
+        if (mEmptyViewLayout == null) {
+            mEmptyViewLayout = new EmptyViewLayout(getContext());
+        }
+        mEmptyViewLayout.setContent(com.cooleshow.base.R.drawable.icon_empty_content, "暂无群成员");
+        mAdapter.setEmptyView(mEmptyViewLayout);
+    }
+
+    @Override
+    public void onGroupUsers(List<GroupMemberBean> groupMemberBeans) {
+        if (isDetached()) {
+            return;
+        }
+        mViewBinding.refreshLayout.finishRefresh();
+        if (mAdapter != null) {
+            if (groupMemberBeans != null && groupMemberBeans.size() > 0) {
+                mDatas = groupMemberBeans;
+                mDecoration.setmDatas(mDatas);
+                mViewBinding.livLetters.setmSourceDatas(mDatas)//设置数据
+                        .invalidate();
+                mAdapter.setNewInstance(groupMemberBeans);
+            } else {
+                mAdapter.getData().clear();
+                mAdapter.notifyDataSetChanged();
+            }
+            checkSelectAllStatus();
+        }
+    }
+
+    @Override
+    public void getListError() {
+        if (isDetached()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mAdapter.getData().clear();
+            mAdapter.notifyDataSetChanged();
+        }
+        mViewBinding.refreshLayout.finishRefresh();
+    }
+
+    @Override
+    public void changeMuteStatusSuccess() {
+        if (isDetached()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mAdapter.clearSelect();
+        }
+        getData();
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.tv_search) {
+            keywords = mViewBinding.etTargetName.getText().toString().trim();
+            getData();
+            mViewBinding.etTargetName.clearFocus();
+            KeyboardUtils.hideSoftInput(mViewBinding.etTargetName);
+            return;
+        }
+
+        if (id == R.id.tv_sure) {
+            ArrayList<String> selectMemberIds = getSelectMemberIds();
+            if (selectMemberIds == null) {
+                ToastUtil.getInstance().showShort("请选择群成员");
+                return;
+            }
+            presenter.changeGroupMuteStatus(groupId, selectMemberIds, false);
+            return;
+        }
+    }
+
+    private ArrayList<String> getSelectMemberIds() {
+        if (mAdapter != null) {
+            ArrayList<GroupMemberBean> selectList = mAdapter.getSelectList();
+            if (selectList != null && selectList.size() > 0) {
+                ArrayList<String> ids = new ArrayList<>();
+                for (int i = 0; i < selectList.size(); i++) {
+                    GroupMemberBean rowsBean = selectList.get(i);
+                    ids.add(rowsBean.getUserId());
+                }
+                return ids;
+            }
+        }
+        return null;
+    }
+
+    private void showSelectListDialog() {
+        if (mSelectListDialog == null) {
+            mSelectListDialog = new MemberSelectListDialog(getContext());
+            mSelectListDialog.setEventListener(new MemberSelectListDialog.OnEventListener() {
+                @Override
+                public void syncList(List<GroupMemberBean> list) {
+                    mAdapter.setSelect(list);
+                    checkSelectAllStatus();
+                }
+            });
+        }
+        if (!mSelectListDialog.isShowing()) {
+            mSelectListDialog.show();
+        }
+        mSelectListDialog.setData(mAdapter.getSelectList());
+    }
+
+    @Override
+    protected FragmentHasMuteMemberLayoutBinding getLayoutView() {
+        return FragmentHasMuteMemberLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected MuteMemberPresenter createPresenter() {
+        return new MuteMemberPresenter();
+    }
+}

+ 127 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/ui/MuteMemberManagerActivity.java

@@ -0,0 +1,127 @@
+package com.cooleshow.chatmodule.ui;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.cooleshow.base.router.RouterPath;
+import com.cooleshow.base.ui.activity.BaseActivity;
+import com.cooleshow.base.utils.Utils;
+import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.adapter.GroupMuteManagerPagerAdapter;
+import com.cooleshow.chatmodule.constants.Constants;
+import com.cooleshow.chatmodule.databinding.AcGroupMuteManagerLayoutBinding;
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
+
+import java.util.ArrayList;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+/**
+ * Author by pq, Date on 2024/5/20.
+ */
+@Route(path = RouterPath.ChatCenter.CHAT_MUTE_MANAGER)
+public class MuteMemberManagerActivity extends BaseActivity<AcGroupMuteManagerLayoutBinding> implements View.OnClickListener {
+    public static final String[] titles = new String[]{"未禁言", "已禁言"};
+
+    private ArrayList<Fragment> fragments = new ArrayList<>();
+    private String groupId;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        QMUIStatusBarHelper.setStatusBarLightMode(this);
+    }
+
+    @Override
+    protected void initView() {
+        Utils.setHeadView(viewBinding.viewStatusBar, this, 0);
+    }
+
+    @Override
+    protected void initData() {
+        super.initData();
+        groupId = getIntent().getStringExtra(Constants.TARGET_ID_KEY);
+        if (TextUtils.isEmpty(groupId)) {
+            finish();
+            return;
+        }
+        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(viewBinding.tabLayout, viewBinding.viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
+            @Override
+            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
+                createTab(tab, titles[position]);
+            }
+        });
+        initListener();
+        NoMuteMemberFragment noMuteMemberFragment = NoMuteMemberFragment.create(groupId);
+        HasMuteMemberFragment hasMuteMemberFragment = HasMuteMemberFragment.create(groupId);
+        fragments.add(noMuteMemberFragment);
+        fragments.add(hasMuteMemberFragment);
+        GroupMuteManagerPagerAdapter muteManagerPagerAdapter = new GroupMuteManagerPagerAdapter(this);
+        muteManagerPagerAdapter.setData(fragments);
+        viewBinding.viewPager.setAdapter(muteManagerPagerAdapter);
+        tabLayoutMediator.attach();
+    }
+
+    private void initListener() {
+        viewBinding.ivBack.setOnClickListener(this);
+        viewBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
+            @Override
+            public void onTabSelected(TabLayout.Tab tab) {
+                if (tab != null && tab.getCustomView() != null) {
+                    View customView = tab.getCustomView();
+                    TextView tv_text = customView.findViewById(R.id.tv_text);
+//                    tv_text.setTextSize(18);
+                    tv_text.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_333333));
+                    tv_text.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
+                }
+            }
+
+            @Override
+            public void onTabUnselected(TabLayout.Tab tab) {
+                if (tab != null && tab.getCustomView() != null) {
+                    View customView = tab.getCustomView();
+                    TextView tv_text = customView.findViewById(R.id.tv_text);
+//                    tv_text.setTextSize(16);
+                    tv_text.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_666666));
+                    tv_text.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
+                }
+            }
+
+            @Override
+            public void onTabReselected(TabLayout.Tab tab) {
+            }
+        });
+    }
+
+
+    private TabLayout.Tab createTab(TabLayout.Tab tab, String text) {
+        View view = LayoutInflater.from(this).inflate(R.layout.view_group_manager_tab_layout, null);
+        TextView tv_text = view.findViewById(R.id.tv_text);
+        tv_text.setText(text);
+        tab.setCustomView(view);
+        return tab;
+    }
+
+    @Override
+    protected AcGroupMuteManagerLayoutBinding getLayoutView() {
+        return AcGroupMuteManagerLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.iv_back) {
+            finish();
+            return;
+        }
+    }
+}

+ 268 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/ui/NoMuteMemberFragment.java

@@ -0,0 +1,268 @@
+package com.cooleshow.chatmodule.ui;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.CompoundButton;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.KeyboardUtils;
+import com.cooleshow.base.utils.SizeUtils;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.widgets.CustomSuspensionDecoration;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.adapter.GroupMemberSelectAvatarListAdapter;
+import com.cooleshow.chatmodule.adapter.MuteMemberListAdapter;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+import com.cooleshow.chatmodule.constants.Constants;
+import com.cooleshow.chatmodule.contract.MuteMemberContract;
+import com.cooleshow.chatmodule.databinding.FragmentNoMuteMemberLayoutBinding;
+import com.cooleshow.chatmodule.presenter.MuteMemberPresenter;
+import com.cooleshow.chatmodule.widget.MemberSelectListDialog;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2024/5/20.
+ */
+public class NoMuteMemberFragment extends BaseMVPFragment<FragmentNoMuteMemberLayoutBinding, MuteMemberPresenter> implements MuteMemberContract.MuteMemberView, View.OnClickListener {
+
+    private MuteMemberListAdapter mAdapter;
+    private EmptyViewLayout mEmptyViewLayout;
+    private CustomSuspensionDecoration mDecoration;
+
+    private List<GroupMemberBean> mDatas = new ArrayList<>();
+
+    private String groupId;
+    private String keywords;
+    private GroupMemberSelectAvatarListAdapter mAvatarListAdapter;
+    private MemberSelectListDialog mSelectListDialog;
+
+    public static NoMuteMemberFragment create(String groupId) {
+        Bundle bundle = new Bundle();
+        bundle.putString(Constants.TARGET_ID_KEY, groupId);
+        NoMuteMemberFragment noMuteMemberFragment = new NoMuteMemberFragment();
+        noMuteMemberFragment.setArguments(bundle);
+        return noMuteMemberFragment;
+    }
+
+    @Override
+    protected void initView(View rootView) {
+
+    }
+
+    @Override
+    protected void initData() {
+        if (getArguments() != null) {
+            groupId = getArguments().getString(Constants.TARGET_ID_KEY, "");
+        }
+        mAdapter = new MuteMemberListAdapter();
+        setEmptyView();
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
+        mViewBinding.recyclerView.setLayoutManager(layoutManager);
+        mDecoration = new CustomSuspensionDecoration(getContext(), mDatas);
+        mDecoration.setColorTitleBg(Color.TRANSPARENT);
+        mDecoration.setmTitleHeight(SizeUtils.dp2px(30));
+        mViewBinding.recyclerView.addItemDecoration(mDecoration);
+        mViewBinding.livLetters.setmPressedShowTextView(mViewBinding.tvHint)//设置HintTextView
+                .setNeedRealIndex(false)//设置需要真实的索引
+                .setmLayoutManager(layoutManager);//设置RecyclerView的LayoutManager
+        mViewBinding.recyclerView.setAdapter(mAdapter);
+
+        mAvatarListAdapter = new GroupMemberSelectAvatarListAdapter();
+        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
+        mViewBinding.recyclerViewSelectAvatar.setLayoutManager(linearLayoutManager);
+        mViewBinding.recyclerViewSelectAvatar.setAdapter(mAvatarListAdapter);
+
+
+        initListener();
+
+    }
+
+    private void getData() {
+        if (TextUtils.isEmpty(groupId)) {
+            return;
+        }
+        presenter.queryGroupMembers(groupId, keywords, false);
+    }
+
+    private void initListener() {
+        mViewBinding.tvSearch.setOnClickListener(this);
+        mViewBinding.tvSure.setOnClickListener(this);
+        mViewBinding.cbAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (mAdapter != null && buttonView.isPressed()) {
+                    mAdapter.selectAll(isChecked);
+                    checkSelectAllStatus();
+                }
+            }
+        });
+        mAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                if (position < mAdapter.getData().size()) {
+                    GroupMemberBean rowsBean = mAdapter.getData().get(position);
+                    mAdapter.setSelect(rowsBean);
+                    checkSelectAllStatus();
+                }
+            }
+        });
+        mViewBinding.refreshLayout.setOnRefreshListener(new OnRefreshListener() {
+            @Override
+            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+                getData();
+            }
+        });
+
+        mAvatarListAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                showSelectListDialog();
+            }
+        });
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getData();
+    }
+
+    private void checkSelectAllStatus() {
+        int selectSize = mAdapter.getSelectList().size();
+        mAvatarListAdapter.setList(mAdapter.getSelectList());
+        boolean selectCurrentAllData = mAdapter.isSelectCurrentAllData();
+        mViewBinding.tvSelectTip.setText(String.format(Locale.getDefault(), "(已选择%d):", selectSize));
+        mViewBinding.cbAll.setChecked(selectCurrentAllData);
+    }
+
+
+    private void setEmptyView() {
+        if (mEmptyViewLayout == null) {
+            mEmptyViewLayout = new EmptyViewLayout(getContext());
+        }
+        mEmptyViewLayout.setContent(com.cooleshow.base.R.drawable.icon_empty_content, "暂无群成员");
+        mAdapter.setEmptyView(mEmptyViewLayout);
+    }
+
+    @Override
+    public void onGroupUsers(List<GroupMemberBean> groupMemberBeans) {
+        if (isDetached()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mViewBinding.refreshLayout.finishRefresh();
+            if (groupMemberBeans != null && groupMemberBeans.size() > 0) {
+                mDatas = groupMemberBeans;
+                mDecoration.setmDatas(mDatas);
+                mViewBinding.livLetters.setmSourceDatas(mDatas)//设置数据
+                        .invalidate();
+                mAdapter.setNewInstance(groupMemberBeans);
+            } else {
+                mAdapter.getData().clear();
+                mAdapter.notifyDataSetChanged();
+            }
+            checkSelectAllStatus();
+        }
+    }
+
+    @Override
+    public void getListError() {
+        if (isDetached()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mAdapter.getData().clear();
+            mAdapter.notifyDataSetChanged();
+        }
+        mViewBinding.refreshLayout.finishRefresh();
+    }
+
+    @Override
+    public void changeMuteStatusSuccess() {
+        if (isDetached()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mAdapter.clearSelect();
+        }
+        getData();
+    }
+
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.tv_search) {
+            keywords = mViewBinding.etTargetName.getText().toString().trim();
+            getData();
+            mViewBinding.etTargetName.clearFocus();
+            KeyboardUtils.hideSoftInput(mViewBinding.etTargetName);
+            return;
+        }
+        if (id == R.id.tv_sure) {
+            ArrayList<String> selectMemberIds = getSelectMemberIds();
+            if (selectMemberIds == null) {
+                ToastUtil.getInstance().showShort("请选择群成员");
+                return;
+            }
+            presenter.changeGroupMuteStatus(groupId, selectMemberIds, true);
+            return;
+        }
+    }
+
+    private ArrayList<String> getSelectMemberIds() {
+        if (mAdapter != null) {
+            ArrayList<GroupMemberBean> selectList = mAdapter.getSelectList();
+            if (selectList != null && selectList.size() > 0) {
+                ArrayList<String> ids = new ArrayList<>();
+                for (int i = 0; i < selectList.size(); i++) {
+                    GroupMemberBean rowsBean = selectList.get(i);
+                    ids.add(rowsBean.getUserId());
+                }
+                return ids;
+            }
+        }
+        return null;
+    }
+
+    private void showSelectListDialog() {
+        if (mSelectListDialog == null) {
+            mSelectListDialog = new MemberSelectListDialog(getContext());
+            mSelectListDialog.setEventListener(new MemberSelectListDialog.OnEventListener() {
+                @Override
+                public void syncList(List<GroupMemberBean> list) {
+                    mAdapter.setSelect(list);
+                    checkSelectAllStatus();
+                }
+            });
+        }
+        if (!mSelectListDialog.isShowing()) {
+            mSelectListDialog.show();
+        }
+        mSelectListDialog.setData(mAdapter.getSelectList());
+    }
+
+    @Override
+    protected FragmentNoMuteMemberLayoutBinding getLayoutView() {
+        return FragmentNoMuteMemberLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected MuteMemberPresenter createPresenter() {
+        return new MuteMemberPresenter();
+    }
+
+}

+ 296 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/ui/TUIChatGroupActivityV2.java

@@ -1,21 +1,43 @@
 package com.cooleshow.chatmodule.ui;
 
 import android.text.TextUtils;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 
 import com.cooleshow.base.common.BaseConstant;
 import com.cooleshow.base.data.net.BaseResponse;
 import com.cooleshow.base.data.net.RetrofitFactory;
 import com.cooleshow.base.utils.ErrorParse;
+import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.widgets.dialog.CommonDialog;
+import com.cooleshow.chatmodule.R;
 import com.cooleshow.chatmodule.api.IMApi;
 import com.cooleshow.chatmodule.bean.IMGroupInfo;
 import com.cooleshow.chatmodule.manager.IMCenter;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.tencent.imsdk.v2.V2TIMGroupChangeInfo;
+import com.tencent.imsdk.v2.V2TIMGroupMemberChangeInfo;
+import com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo;
+import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
+import com.tencent.imsdk.v2.V2TIMGroupTipsElem;
+import com.tencent.imsdk.v2.V2TIMManager;
+import com.tencent.imsdk.v2.V2TIMMessage;
+import com.tencent.imsdk.v2.V2TIMValueCallback;
 import com.tencent.qcloud.tuicore.TUIConstants;
+import com.tencent.qcloud.tuikit.timcommon.bean.MessageReceiptInfo;
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
 import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
+import com.tencent.qcloud.tuikit.tuichat.TUIChatService;
 import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo;
 import com.tencent.qcloud.tuikit.tuichat.bean.GroupInfo;
 import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIGroupChatActivity;
+import com.tencent.qcloud.tuikit.tuichat.classicui.widget.input.InputView;
+import com.tencent.qcloud.tuikit.tuichat.interfaces.GroupChatEventListener;
+import com.tencent.qcloud.tuikit.tuigroup.model.GroupInfoProvider;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import io.reactivex.rxjava3.annotations.NonNull;
@@ -24,15 +46,24 @@ import io.reactivex.rxjava3.core.Observer;
 import io.reactivex.rxjava3.disposables.Disposable;
 import io.reactivex.rxjava3.schedulers.Schedulers;
 
+import static com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_ROLE_ADMIN;
+import static com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
+import static com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_ROLE_OWNER;
+
 /**
  * Author by pq, Date on 2023/8/8.
  * 为了实现checkInGroup这个逻辑,所以继承TUIGroupChatActivity
  */
 public class TUIChatGroupActivityV2 extends TUIGroupChatActivity {
+    public static final String TAG = "TUIChatGroupActivityV2";
     public static int GROUP_INFO_ERROR = 204;//群组相关信息异常
     private String groupId;
     private CommonDialog mTipdialog;
     private String conversationId;
+    private GroupInfoProvider mGroupInfoProvider;
+    private String currentImUserId;
+    private GroupChatEventListener mGroupChatEventListener;
+    private View muteInputView;
 
     @Override
     public void initChat(ChatInfo chatInfo) {
@@ -40,11 +71,271 @@ public class TUIChatGroupActivityV2 extends TUIGroupChatActivity {
         conversationId = getIntent().getStringExtra(TUIConstants.TUIChat.CONVERSATION_ID);
         GroupInfo groupInfo = (GroupInfo) chatInfo;
         groupId = groupInfo.getId();
+        currentImUserId = UserHelper.getImUserId();
         if (groupInfo != null) {
             checkInGroup(groupInfo.getId());
+            loadGroupInfo();
+            addListener();
+        }
+    }
+
+    private void addListener() {
+        if (mGroupChatEventListener == null) {
+            mGroupChatEventListener = new GroupChatEventListener() {
+                @Override
+                public void onGroupForceExit(String groupId) {
+                }
+
+                @Override
+                public void exitGroupChat(String chatId) {
+                }
+
+                @Override
+                public void clearGroupMessage(String chatId) {
+                }
+
+                @Override
+                public void onApplied() {
+                }
+
+                @Override
+                public void handleRevoke(String msgId) {
+                }
+
+                @Override
+                public void onRecvNewMessage(TUIMessageBean message) {
+                    LOG.i(TAG, "onRecvNewMessage");
+                    if (!TextUtils.equals(message.getGroupId(), groupId)) {
+                        LOG.i(TAG, "receive a new message , not belong to current chat.");
+                    } else {
+                        handleRecvNewMessage(message);
+                    }
+                }
+
+                @Override
+                public void onReadReport(List<MessageReceiptInfo> receiptInfoList) {
+                }
+
+                @Override
+                public void onGroupNameChanged(String groupId, String newName) {
+                }
+
+                @Override
+                public void onGroupFaceUrlChanged(String groupId, String faceUrl) {
+                }
+
+                @Override
+                public void onRecvMessageModified(TUIMessageBean messageBean) {
+                }
+
+                @Override
+                public void addMessage(TUIMessageBean messageBean, String chatId) {
+                }
+
+                @Override
+                public void onMessageChanged(TUIMessageBean messageBean, int dataChangeType) {
+                }
+            };
+            TUIChatService.getInstance().addGroupChatEventListener(mGroupChatEventListener);
         }
     }
 
+    private void handleRecvNewMessage(TUIMessageBean message) {
+        V2TIMMessage v2TIMMessage = message.getV2TIMMessage();
+        V2TIMGroupTipsElem groupTipElem = v2TIMMessage.getGroupTipsElem();
+        if (groupTipElem == null) {
+            return;
+        }
+        int tipsType = groupTipElem.getType();
+        if (tipsType == V2TIMGroupTipsElem.V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE) {
+            List<V2TIMGroupChangeInfo> modifyList = groupTipElem.getGroupChangeInfoList();
+            for (int i = 0; i < modifyList.size(); i++) {
+                V2TIMGroupChangeInfo modifyInfo = modifyList.get(i);
+                int modifyType = modifyInfo.getType();
+                if (modifyType == V2TIMGroupChangeInfo.V2TIM_GROUP_INFO_CHANGE_TYPE_SHUT_UP_ALL) {
+                    boolean isShutUpAll = modifyInfo.getBoolValue();
+                    if (isShutUpAll) {
+                        //禁言全员
+                        LOG.i(TAG, "禁言全员");
+                        TUIChatGroupActivityV2.this.isMuteAll = true;
+                    } else {
+                        //取消禁言全员
+                        LOG.i(TAG, "取消禁言全员");
+                        TUIChatGroupActivityV2.this.isMuteAll = false;
+                    }
+                    handleMuteLayout();
+                    return;
+                }
+                if (modifyType == V2TIMGroupChangeInfo.V2TIM_GROUP_INFO_CHANGE_TYPE_OWNER) {
+                    //群主变化
+                    handleOwnerChange(groupTipElem);
+                    return;
+                }
+            }
+        }
+
+        if (tipsType == V2TIMGroupTipsElem.V2TIM_GROUP_TIPS_TYPE_SET_ADMIN) {
+            //管理员变化
+            handleAdminChange(groupTipElem, true);
+            return;
+        }
+
+        if (tipsType == V2TIMGroupTipsElem.V2TIM_GROUP_TIPS_TYPE_CANCEL_ADMIN) {
+            //取消管理员
+            handleAdminChange(groupTipElem, false);
+        }
+
+        if (tipsType == V2TIMGroupTipsElem.V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE) {
+            List<V2TIMGroupMemberChangeInfo> modifyList = groupTipElem.getMemberChangeInfoList();
+            if (modifyList.size() > 0) {
+                V2TIMGroupMemberChangeInfo v2TIMGroupMemberChangeInfo = modifyList.get(0);
+                String userID = v2TIMGroupMemberChangeInfo.getUserID();
+                if (TextUtils.equals(userID, currentImUserId)) {
+                    long shutupTime = v2TIMGroupMemberChangeInfo.getMuteTime();
+                    if (shutupTime > 0) {
+                        //禁言个人
+                        LOG.i(TAG, "禁言个人:" + userID);
+                        TUIChatGroupActivityV2.this.isMuteUser = true;
+                    } else {
+                        //取消禁言个人
+                        LOG.i(TAG, "取消禁言个人:" + userID);
+                        TUIChatGroupActivityV2.this.isMuteUser = false;
+                    }
+                    handleMuteLayout();
+                }
+            }
+        }
+
+    }
+
+    private String getTargetId(V2TIMGroupTipsElem groupTipElem) {
+        if (groupTipElem == null) {
+            return null;
+        }
+        List<V2TIMGroupMemberInfo> v2TIMGroupMemberInfoList = groupTipElem.getMemberList();
+        if (v2TIMGroupMemberInfoList != null && v2TIMGroupMemberInfoList.size() > 0) {
+            V2TIMGroupMemberInfo v2TIMGroupMemberInfo = v2TIMGroupMemberInfoList.get(0);
+            LOG.i(TAG, "变化:" + v2TIMGroupMemberInfo.getUserID());
+            LOG.i(TAG, "变化:" + v2TIMGroupMemberInfo.getNickName());
+            return v2TIMGroupMemberInfo.getUserID();
+        }
+        return null;
+    }
+
+    private void handleOwnerChange(V2TIMGroupTipsElem groupTipElem) {
+        String targetId = getTargetId(groupTipElem);
+        if (TextUtils.isEmpty(targetId)) {
+            return;
+        }
+        LOG.i(TAG, "群主变化:" + targetId);
+        boolean equals = TextUtils.equals(targetId, currentImUserId);
+        role = equals ? V2TIM_GROUP_MEMBER_ROLE_OWNER : V2TIM_GROUP_MEMBER_ROLE_MEMBER;
+        handleMuteLayout();
+    }
+
+    private void handleAdminChange(V2TIMGroupTipsElem groupTipElem, boolean isAdd) {
+        String targetId = getTargetId(groupTipElem);
+        if (TextUtils.isEmpty(targetId)) {
+            return;
+        }
+        LOG.i(TAG, "管理员变化:" + targetId + "--isAdd:" + isAdd);
+        if (TextUtils.equals(targetId, currentImUserId)) {
+            role = isAdd ? V2TIM_GROUP_MEMBER_ROLE_ADMIN : V2TIM_GROUP_MEMBER_ROLE_MEMBER;
+            handleMuteLayout();
+        }
+    }
+
+    private boolean getMuteResult() {
+        LOG.i(TAG, "isMuteUser:" + isMuteUser);
+        if (isMuteUser) {
+            return true;
+        }
+        boolean adminOrOWNER = isAdminOrOWNER();
+        LOG.i(TAG, "isAdminOrOWNER:" + adminOrOWNER);
+        if (adminOrOWNER) {
+            return false;
+        }
+        LOG.i(TAG, "isMuteAll:" + isMuteAll);
+        if (isMuteAll) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isAdminOrOWNER() {
+        return role == V2TIM_GROUP_MEMBER_ROLE_ADMIN || role == V2TIM_GROUP_MEMBER_ROLE_OWNER;
+    }
+
+    private boolean isMuteAll = false;
+    private boolean isMuteUser = false;
+    private int role = V2TIM_GROUP_MEMBER_ROLE_MEMBER;
+
+    private void loadGroupInfo() {
+        if (mGroupInfoProvider == null) {
+            mGroupInfoProvider = new GroupInfoProvider();
+        }
+        mGroupInfoProvider.loadGroupInfo(groupId, new IUIKitCallback<com.tencent.qcloud.tuikit.tuigroup.bean.GroupInfo>() {
+            @Override
+            public void onSuccess(com.tencent.qcloud.tuikit.tuigroup.bean.GroupInfo data) {
+                TUIChatGroupActivityV2.this.isMuteAll = data.isAllMuted();
+                LOG.i(TAG, "Thread:" + Thread.currentThread().getName());
+                getGroupMemberInfo();
+                LOG.i(TAG, "allMuted:" + isMuteAll);
+            }
+
+            @Override
+            public void onError(String module, int errCode, String errMsg) {
+            }
+        });
+    }
+
+    private void getGroupMemberInfo() {
+        ArrayList<String> strings = new ArrayList<>();
+        strings.add(currentImUserId);
+        V2TIMManager.getGroupManager().getGroupMembersInfo(groupId, strings, new V2TIMValueCallback<List<V2TIMGroupMemberFullInfo>>() {
+            @Override
+            public void onSuccess(List<V2TIMGroupMemberFullInfo> v2TIMGroupMemberFullInfos) {
+                if (v2TIMGroupMemberFullInfos != null && v2TIMGroupMemberFullInfos.size() > 0) {
+                    V2TIMGroupMemberFullInfo v2TIMGroupMemberFullInfo = v2TIMGroupMemberFullInfos.get(0);
+                    TUIChatGroupActivityV2.this.role = v2TIMGroupMemberFullInfo.getRole();
+                    LOG.i(TAG, "查询role:" + role);
+                    long l = IMCenter.getInstance().getServerTime();
+                    TUIChatGroupActivityV2.this.isMuteUser = v2TIMGroupMemberFullInfo.getMuteUntil() > l;
+                    handleMuteLayout();
+                }
+            }
+
+            @Override
+            public void onError(int i, String s) {
+
+            }
+        });
+    }
+
+    private void handleMuteLayout() {
+        boolean muteResult = getMuteResult();
+        changeMuteLayoutVisibility(muteResult);
+    }
+
+    private void changeMuteLayoutVisibility(Boolean flag) {
+        if (flag != null && chatFragment!=null) {
+            InputView inputLayout = chatFragment.getChatView().getInputLayout();
+            ViewGroup inputMuteContainer = inputLayout.getInputMuteContainer();
+            if (inputMuteContainer.getChildCount() == 0) {
+                View muteView = getMuteView(inputMuteContainer);
+                inputMuteContainer.addView(muteView);
+            }
+            inputLayout.controlMuteViewVisibility(flag ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    private View getMuteView(ViewGroup inputMuteContainer) {
+        if (muteInputView == null) {
+            muteInputView = LayoutInflater.from(this).inflate(R.layout.view_mute_input_layout, inputMuteContainer, false);
+        }
+        return muteInputView;
+    }
+
 
     private void checkInGroup(String groupId) {
         //根据用户编号获取用户基本信息
@@ -114,4 +405,9 @@ public class TUIChatGroupActivityV2 extends TUIGroupChatActivity {
             }
         });
     }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
 }

+ 142 - 0
chatModule/src/main/java/com/cooleshow/chatmodule/widget/MemberSelectListDialog.java

@@ -0,0 +1,142 @@
+package com.cooleshow.chatmodule.widget;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemChildClickListener;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.base.widgets.dialog.BaseFullDialog;
+import com.cooleshow.chatmodule.R;
+import com.cooleshow.chatmodule.adapter.GroupMemberSelectListDialogAdapter;
+import com.cooleshow.chatmodule.bean.GroupMemberBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2024/2/20.
+ */
+public class MemberSelectListDialog extends BaseFullDialog implements View.OnClickListener {
+
+    private RecyclerView mRecyclerView;
+    private GroupMemberSelectListDialogAdapter mListAdapter;
+
+    private OnEventListener mEventListener;
+    private TextView mTvTitle;
+    private TextView mTvOk;
+
+    public MemberSelectListDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.BottomDialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_group_select_list_layout);
+        Window window = getWindow();
+        //设置dialog在屏幕底部
+        window.setGravity(Gravity.BOTTOM);
+        //设置dialog弹出时的动画效果,从屏幕底部向上弹出
+        window.setWindowAnimations(com.cooleshow.base.R.style.BottomAnimation);
+        window.getDecorView().setPadding(0, 0, 0, 0);
+        //获得window窗口的属性
+        WindowManager.LayoutParams lp = window.getAttributes();
+        //设置窗口宽度为充满全屏
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        //设置窗口高度为包裹内容
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.horizontalMargin = 0;
+        lp.verticalMargin = 0;
+        //将设置好的属性set回去
+        window.setAttributes(lp);
+        initView();
+        initData();
+        initListener();
+    }
+
+    private void initView() {
+        mTvTitle = findViewById(R.id.tv_title);
+        mTvOk = findViewById(R.id.tv_ok);
+        mRecyclerView = findViewById(R.id.recyclerView);
+    }
+
+    private void initData() {
+        mListAdapter = new GroupMemberSelectListDialogAdapter();
+        EmptyViewLayout emptyViewLayout = new EmptyViewLayout(getContext());
+        emptyViewLayout.setContent(com.cooleshow.base.R.drawable.icon_empty_content, "暂无学生");
+        mListAdapter.setEmptyView(emptyViewLayout);
+        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
+        mRecyclerView.setLayoutManager(linearLayoutManager);
+        mRecyclerView.setAdapter(mListAdapter);
+    }
+
+    private void initListener() {
+        findViewById(R.id.iv_close).setOnClickListener(this);
+        mTvOk.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dismiss();
+            }
+        });
+        mListAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
+            @Override
+            public void onItemChildClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                int id = view.getId();
+                if (id == R.id.iv_del) {
+                    if (position < mListAdapter.getData().size()) {
+                        mListAdapter.removeAt(position);
+                        setNum(String.valueOf(mListAdapter.getData().size()));
+                        if (mEventListener != null) {
+                            mEventListener.syncList(mListAdapter.getData());
+                        }
+                    }
+                    return;
+                }
+            }
+        });
+    }
+
+    public void setData(ArrayList<GroupMemberBean> datas) {
+        mListAdapter.getData().clear();
+        mListAdapter.notifyDataSetChanged();
+        if (datas != null && datas.size() > 0) {
+            setNum(String.valueOf(datas.size()));
+            if (mListAdapter != null) {
+                mListAdapter.setList(datas);
+            }
+        } else {
+            setNum(String.valueOf(0));
+        }
+    }
+
+    private void setNum(String num) {
+        mTvTitle.setText(String.format("已选择 (%s)", num));
+    }
+
+    public void setEventListener(OnEventListener eventListener) {
+        mEventListener = eventListener;
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.iv_close) {
+            dismiss();
+            return;
+        }
+    }
+
+    public interface OnEventListener {
+        void syncList(List<GroupMemberBean> list);
+    }
+}

BIN
chatModule/src/main/res/drawable-xhdpi/icon_chat_mute_tip.png


BIN
chatModule/src/main/res/drawable-xxhdpi/icon_chat_mute_tip.png


+ 54 - 0
chatModule/src/main/res/layout/ac_group_mute_manager_layout.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <View
+        android:id="@+id/view_status_bar"
+        android:layout_width="match_parent"
+        android:layout_height="1px"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        app:layout_constraintBottom_toBottomOf="@+id/tab_layout"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tab_layout"
+        android:id="@+id/iv_back"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:padding="13dp"
+        android:src="@drawable/icon_back_black" />
+
+    <com.google.android.material.tabs.TabLayout
+        android:id="@+id/tab_layout"
+        android:layout_width="wrap_content"
+        android:layout_height="44dp"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_status_bar"
+        app:tabBackground="@color/transparent"
+        app:tabGravity="center"
+        app:tabIndicator="@drawable/custom_indicator_drawable"
+        app:tabIndicatorColor="@color/colorAccent"
+        app:tabIndicatorFullWidth="false"
+        app:tabIndicatorHeight="4dp"
+        app:tabMaxWidth="0dp"
+        app:tabPaddingEnd="0dp"
+        app:tabPaddingStart="0dp"
+        app:tabRippleColor="@color/transparent"
+        app:tabSelectedTextColor="@color/color_333333"
+        app:tabTextColor="@color/color_666666" />
+
+
+    <androidx.viewpager2.widget.ViewPager2
+        android:id="@+id/viewPager"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/dp_12"
+        android:overScrollMode="never"
+        android:scrollbars="none"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 58 - 0
chatModule/src/main/res/layout/dialog_group_select_list_layout.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="600dp"
+    android:background="@drawable/bg_white_top_20dp">
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_16"
+        android:textStyle="bold"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="已选择 (40)" />
+
+    <TextView
+        android:id="@+id/tv_ok"
+        android:layout_width="52dp"
+        android:layout_height="26dp"
+        android:layout_marginEnd="20dp"
+        android:background="@drawable/shape_2dc7aa_3dp"
+        android:gravity="center"
+        android:text="确定"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+    <ImageView
+        android:id="@+id/iv_close"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:padding="16dp"
+        android:src="@drawable/icon_close_black"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:paddingEnd="20dp"
+        android:paddingStart="20dp"
+        android:layout_marginTop="20dp"
+        android:id="@+id/recyclerView"
+        android:scrollbars="none"
+        android:overScrollMode="never"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 215 - 0
chatModule/src/main/res/layout/fragment_has_mute_member_layout.xml

@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:tools="http://schemas.android.com/tools">
+    <View
+        android:background="@color/transparent"
+        android:id="@+id/view_top_bg"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_filter"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"/>
+
+    <View
+        android:id="@+id/view_search_bg"
+        android:layout_width="0dp"
+        android:layout_height="35dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="14dp"
+        android:background="@drawable/bg_white_18dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_search_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="12dp"
+        android:src="@drawable/icon_search"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toLeftOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <com.cooleshow.base.widgets.ClearEditText
+        android:id="@+id/et_target_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:background="@null"
+        android:ellipsize="end"
+        android:hint="请输入群成员名称"
+        android:maxLines="1"
+        android:paddingStart="8dp"
+        android:textColorHint="@color/color_999999"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toRightOf="@+id/iv_search_icon"
+        app:layout_constraintRight_toLeftOf="@+id/tv_search"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <TextView
+        android:id="@+id/tv_search"
+        android:layout_width="56dp"
+        android:layout_height="28dp"
+        android:layout_marginEnd="4dp"
+        android:background="@drawable/shape_2dc7aa_18dp"
+        android:gravity="center"
+        android:text="搜索"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintRight_toRightOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/group_search"
+        app:constraint_referenced_ids="tv_search,et_target_name,iv_search_icon,view_search_bg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+    <com.scwang.smart.refresh.layout.SmartRefreshLayout
+        android:id="@+id/refreshLayout"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:srlEnableLoadMore="false"
+        app:layout_constraintBottom_toTopOf="@+id/view_bottom_bg"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_search_bg">
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recyclerView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginTop="@dimen/dp_10"
+            android:scrollbars="none"
+            android:overScrollMode="never"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/liv_letters"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/view_search_bg"
+            app:layout_constraintVertical_bias="0.0"/>
+    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+
+    <com.mcxtzhang.indexlib.IndexBar.widget.IndexBar
+        android:id="@+id/liv_letters"
+        android:layout_width="@dimen/dp_20"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/dp_45"
+        android:layout_marginBottom="@dimen/dp_20"
+        android:paddingRight="@dimen/dp_10"
+        android:layout_marginEnd="8dp"
+        app:indexBarPressBackground="@color/white"
+        app:indexBarTextSize="@dimen/dp_12"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintVertical_bias="0.0"/>
+
+    <View
+        android:id="@+id/spacer"
+        android:layout_width="@dimen/dp_58"
+        android:layout_height="@dimen/dp_58"
+        android:layout_marginEnd="@dimen/dp_5"
+        android:gravity="center"
+        android:paddingStart="8dp"
+        android:paddingBottom="@dimen/dp_3"
+        android:text="A"
+        android:textColor="@color/white"
+        android:textSize="@dimen/dp_45"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toTopOf="@id/liv_letters"
+        app:layout_constraintRight_toLeftOf="@+id/liv_letters"/>
+
+    <TextView
+        android:id="@+id/tv_hint"
+        android:layout_width="@dimen/dp_58"
+        android:layout_height="@dimen/dp_58"
+        android:layout_marginTop="@dimen/dp_54"
+        android:background="@drawable/tc_ic_teacher_screen"
+        android:gravity="center"
+        android:paddingStart="8dp"
+        android:paddingBottom="@dimen/dp_3"
+        android:text="A"
+        android:textColor="@color/white"
+        android:textSize="@dimen/dp_45"
+        android:textStyle="bold"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="@+id/spacer"
+        app:layout_constraintTop_toTopOf="@id/spacer"/>
+
+
+    <View
+        android:id="@+id/view_bottom_bg"
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        android:background="@color/white"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/color_f2f2f2"
+        app:layout_constraintLeft_toLeftOf="@+id/view_bottom_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_bottom_bg" />
+
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="80dp"
+        android:layout_height="30dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="@dimen/dp_13"
+        android:background="@drawable/shape_2dc7aa_20dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        android:textStyle="bold"
+        android:text="解除禁言"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/view_bottom_bg"
+        tools:text="解除禁言" />
+
+    <CheckBox
+        android:id="@+id/cb_all"
+        android:layout_width="wrap_content"
+        android:layout_height="40dp"
+        android:layout_marginStart="13dp"
+        android:background="@color/transparent"
+        android:button="@drawable/common_check_selector2"
+        android:gravity="center"
+        android:paddingStart="12dp"
+        android:text="全选"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_select_tip"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_select_tip" />
+
+    <TextView
+        android:id="@+id/tv_select_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:text="(已选择0):"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_sure"
+        app:layout_constraintLeft_toRightOf="@+id/cb_all"
+        app:layout_constraintTop_toTopOf="@+id/tv_sure" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recyclerView_select_avatar"
+        android:layout_width="0dp"
+        android:layout_height="28dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="10dp"
+        android:overScrollMode="never"
+        android:scrollbars="none"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_sure"
+        app:layout_constraintLeft_toRightOf="@+id/tv_select_tip"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toTopOf="@+id/tv_sure" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 214 - 0
chatModule/src/main/res/layout/fragment_no_mute_member_layout.xml

@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:tools="http://schemas.android.com/tools">
+    <View
+        android:background="@color/transparent"
+        android:id="@+id/view_top_bg"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_filter"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"/>
+    <View
+        android:id="@+id/view_search_bg"
+        android:layout_width="0dp"
+        android:layout_height="35dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="14dp"
+        android:background="@drawable/bg_white_18dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_search_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="12dp"
+        android:src="@drawable/icon_search"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toLeftOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <com.cooleshow.base.widgets.ClearEditText
+        android:id="@+id/et_target_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:background="@null"
+        android:ellipsize="end"
+        android:hint="请输入群成员名称"
+        android:maxLines="1"
+        android:paddingStart="8dp"
+        android:textColorHint="@color/color_999999"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toRightOf="@+id/iv_search_icon"
+        app:layout_constraintRight_toLeftOf="@+id/tv_search"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <TextView
+        android:id="@+id/tv_search"
+        android:layout_width="56dp"
+        android:layout_height="28dp"
+        android:layout_marginEnd="4dp"
+        android:background="@drawable/shape_2dc7aa_18dp"
+        android:gravity="center"
+        android:text="搜索"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintRight_toRightOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/group_search"
+        app:constraint_referenced_ids="tv_search,et_target_name,iv_search_icon,view_search_bg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+    <com.scwang.smart.refresh.layout.SmartRefreshLayout
+        android:id="@+id/refreshLayout"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:srlEnableLoadMore="false"
+        app:layout_constraintBottom_toTopOf="@+id/view_bottom_bg"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_search_bg">
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recyclerView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginTop="@dimen/dp_10"
+            android:scrollbars="none"
+            android:overScrollMode="never"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/liv_letters"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/view_search_bg"
+            app:layout_constraintVertical_bias="0.0"/>
+    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+
+    <com.mcxtzhang.indexlib.IndexBar.widget.IndexBar
+        android:id="@+id/liv_letters"
+        android:layout_width="@dimen/dp_20"
+        android:layout_marginEnd="8dp"
+        android:layout_height="0dp"
+        android:layout_marginTop="@dimen/dp_45"
+        android:layout_marginBottom="@dimen/dp_20"
+        android:paddingRight="@dimen/dp_10"
+        app:indexBarPressBackground="@color/white"
+        app:indexBarTextSize="@dimen/dp_12"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintVertical_bias="0.0"/>
+
+    <View
+        android:id="@+id/spacer"
+        android:layout_width="@dimen/dp_58"
+        android:layout_height="@dimen/dp_58"
+        android:layout_marginEnd="@dimen/dp_5"
+        android:gravity="center"
+        android:paddingStart="8dp"
+        android:paddingBottom="@dimen/dp_3"
+        android:text="A"
+        android:textColor="@color/white"
+        android:textSize="@dimen/dp_45"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toTopOf="@id/liv_letters"
+        app:layout_constraintRight_toLeftOf="@+id/liv_letters"/>
+
+    <TextView
+        android:id="@+id/tv_hint"
+        android:layout_width="@dimen/dp_58"
+        android:layout_height="@dimen/dp_58"
+        android:layout_marginTop="@dimen/dp_54"
+        android:background="@drawable/tc_ic_teacher_screen"
+        android:gravity="center"
+        android:paddingStart="8dp"
+        android:paddingBottom="@dimen/dp_3"
+        android:text="A"
+        android:textColor="@color/white"
+        android:textSize="@dimen/dp_45"
+        android:textStyle="bold"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="@+id/spacer"
+        app:layout_constraintTop_toTopOf="@id/spacer"/>
+
+
+    <View
+        android:id="@+id/view_bottom_bg"
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        android:background="@color/white"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/color_f2f2f2"
+        app:layout_constraintLeft_toLeftOf="@+id/view_bottom_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_bottom_bg" />
+
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="80dp"
+        android:layout_height="30dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="@dimen/dp_13"
+        android:background="@drawable/shape_2dc7aa_20dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        android:textStyle="bold"
+        android:text="禁言"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/view_bottom_bg"
+        tools:text="禁言" />
+
+    <CheckBox
+        android:id="@+id/cb_all"
+        android:layout_width="wrap_content"
+        android:layout_height="40dp"
+        android:layout_marginStart="13dp"
+        android:background="@color/transparent"
+        android:button="@drawable/common_check_selector2"
+        android:gravity="center"
+        android:paddingStart="12dp"
+        android:text="全选"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_select_tip"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_select_tip" />
+
+    <TextView
+        android:id="@+id/tv_select_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:text="(已选择0):"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_sure"
+        app:layout_constraintLeft_toRightOf="@+id/cb_all"
+        app:layout_constraintTop_toTopOf="@+id/tv_sure" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recyclerView_select_avatar"
+        android:layout_width="0dp"
+        android:layout_height="28dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="10dp"
+        android:overScrollMode="never"
+        android:scrollbars="none"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_sure"
+        app:layout_constraintLeft_toRightOf="@+id/tv_select_tip"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toTopOf="@+id/tv_sure" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 44 - 0
chatModule/src/main/res/layout/item_group_select_list_dialog_layout.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="20dp">
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:id="@+id/iv_avatar"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:paddingStart="12dp"
+        android:paddingEnd="12dp"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintRight_toLeftOf="@+id/iv_del"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar" />
+
+    <ImageView
+        android:id="@+id/iv_del"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="6dp"
+        android:src="@drawable/icon_close_bg"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 112 - 0
chatModule/src/main/res/layout/item_mute_member_list_layout.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:id="@+id/root_view"
+    android:background="@color/white"
+    android:paddingStart="@dimen/dp_14">
+
+    <ImageView
+        android:id="@+id/iv_check"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
+        app:layout_constraintTop_toTopOf="@+id/iv_icon"
+        android:src="@drawable/icon_box_normal2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:layout_marginTop="12dp"
+        android:id="@+id/iv_icon"
+        android:layout_width="@dimen/dp_44"
+        android:layout_height="@dimen/dp_44"
+        android:layout_marginStart="12dp"
+        android:layout_marginBottom="12dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toRightOf="@+id/iv_check"
+        app:layout_constraintTop_toTopOf="parent"
+        app:qmui_corner_radius="6dp" />
+
+    <TextView
+        android:textStyle="bold"
+        android:id="@+id/tv_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="11dp"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_1a1a1a"
+        android:textSize="@dimen/sp_16"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_icon"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toRightOf="@+id/iv_icon"
+        app:layout_constraintRight_toLeftOf="@+id/tv_group_tag"
+        app:layout_constraintTop_toTopOf="@+id/iv_icon"
+        app:layout_constraintWidth_default="wrap"
+        tools:text="哈喽王哈喽王哈喽王哈喽王哈喽王哈喽王" />
+
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/tv_des"
+        android:paddingEnd="25dp"
+        android:maxLines="2"
+        android:ellipsize="end"
+        app:layout_constraintRight_toRightOf="parent"
+        android:layout_width="0dp"
+        android:includeFontPadding="false"
+        android:layout_height="wrap_content"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_12"
+        android:layout_marginTop="5dp"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_name"
+        app:layout_constraintTop_toBottomOf="@+id/tv_name"
+        tools:text="" />
+
+    <TextView
+        android:paddingTop="1dp"
+        android:paddingBottom="1dp"
+        android:paddingStart="6dp"
+        android:paddingEnd="6dp"
+        android:visibility="gone"
+        android:layout_marginLeft="@dimen/dp_4"
+        android:layout_marginEnd="12dp"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_name"
+        app:layout_constraintTop_toTopOf="@+id/tv_name"
+        android:id="@+id/tv_group_tag"
+        app:layout_constraintLeft_toRightOf="@+id/tv_name"
+        app:layout_constraintRight_toRightOf="parent"
+        android:gravity="center"
+        android:background="@drawable/shape_2dc7aa_4dp"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_11"
+        android:text="晋升团"
+        tools:visibility="visible"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <ImageView
+        android:id="@+id/im_group_mark"
+        android:layout_width="@dimen/dp_45"
+        android:layout_height="@dimen/dp_17"
+        android:layout_marginLeft="@dimen/dp_4"
+        android:visibility="gone"
+        android:layout_marginEnd="12dp"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_name"
+        app:layout_constraintLeft_toRightOf="@+id/tv_name"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_name" />
+
+    <View
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_marginTop="13dp"
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:background="@color/divide_color_f0f0f0"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_name" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 11 - 0
chatModule/src/main/res/layout/item_student_select_avatar_layout.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="28dp">
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:id="@+id/iv_avatar"
+        android:layout_width="28dp"
+        android:layout_marginEnd="6dp"
+        android:layout_height="28dp" />
+</FrameLayout>

+ 33 - 0
chatModule/src/main/res/layout/tc_activity_chat_group_setting.xml

@@ -215,6 +215,39 @@
                     android:textSize="@dimen/dp_16" />
             </LinearLayout>
 
+            <CheckBox
+                android:id="@+id/cb_mute"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/dp_50"
+                android:layout_marginTop="1dp"
+                android:background="@color/white"
+                android:button="@null"
+                android:checked="false"
+                android:drawableEnd="@drawable/tc_switch_selector"
+                android:paddingStart="@dimen/dp_13"
+                android:paddingEnd="@dimen/dp_15"
+                android:text="学生禁言"
+                android:textColor="@color/color_333333"
+                android:textSize="@dimen/sp_16"
+                android:visibility="gone"
+                tools:visibility="visible" />
+
+            <TextView
+                android:id="@+id/tv_mute_member_manager"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/dp_50"
+                android:layout_marginTop="1dp"
+                android:background="@color/white"
+                android:drawableEnd="@drawable/icon_arrow_right"
+                android:gravity="center_vertical"
+                android:paddingStart="@dimen/dp_13"
+                android:paddingRight="@dimen/dp_15"
+                android:text="禁言名单"
+                android:textColor="@color/color_333333"
+                android:textSize="@dimen/sp_16"
+                android:visibility="gone"
+                tools:visibility="visible" />
+
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="50dp"

+ 18 - 0
chatModule/src/main/res/layout/view_group_manager_tab_layout.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_gravity="center"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        tools:text="哈哈"
+        android:layout_marginTop="3dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:textSize="@dimen/sp_16"
+        android:textColor="@color/color_666666"
+        android:id="@+id/tv_text"
+        android:minWidth="80dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+</FrameLayout>

+ 32 - 0
chatModule/src/main/res/layout/view_mute_input_layout.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:background="@color/white"
+    android:layout_height="match_parent">
+
+    <View
+        android:background="@color/color_f2f2f2"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"/>
+
+    <FrameLayout
+        android:layout_gravity="center"
+        android:layout_marginEnd="12dp"
+        android:layout_marginStart="12dp"
+        android:background="@drawable/shape_f2f2f2_6dp"
+        android:layout_width="match_parent"
+        android:layout_height="36dp">
+
+        <TextView
+            android:includeFontPadding="false"
+            android:drawablePadding="5dp"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableStart="@drawable/icon_chat_mute_tip"
+            android:text="禁言中"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_15"
+            android:textStyle="bold" />
+    </FrameLayout>
+</FrameLayout>