空格
51
tuiconversation/build.gradle
Normal file
@@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
namespace "com.tencent.qcloud.tuikit.tuiconversation"
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 30
|
||||
}
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
res.srcDirs += "src/main/res-minimalistui"
|
||||
res.srcDirs += "src/main/res-light"
|
||||
res.srcDirs += "src/main/res-lively"
|
||||
res.srcDirs += "src/main/res-serious"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/*plugin-build-Begin
|
||||
|
||||
compileOnly fileTree(include: ['*.jar','*.aar'], dir: '../../../../tuikit/android/libs')
|
||||
|
||||
plugin-build-End*/
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'com.google.code.gson:gson:2.9.1'
|
||||
implementation project(':tuichat')
|
||||
annotationProcessor 'com.google.auto.service:auto-service:1.1.1'
|
||||
|
||||
api project(':timcommon')
|
||||
api project(':moduleUtil')
|
||||
}
|
||||
33
tuiconversation/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
|
||||
<!-- **************** Classic UI Activity Start **************** -->
|
||||
<activity
|
||||
android:name="com.tencent.qcloud.tuikit.tuiconversation.classicui.page.TUIForwardSelectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.tencent.qcloud.tuikit.tuiconversation.classicui.page.TUIFoldedConversationActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<!-- **************** Classic UI Activity End **************** -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- **************** Minimalist UI Activity Start **************** -->
|
||||
<activity
|
||||
android:name="com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page.TUIForwardSelectMinimalistActivity"
|
||||
android:theme="@style/ConversationTransparentPopActivityStyle"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page.TUIFoldedConversationMinimalistActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<!-- **************** Minimalist UI Activity End **************** -->
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation;
|
||||
|
||||
public class TUIConversationConstants {
|
||||
public static final String FORWARD_SELECT_CONVERSATION_KEY = "forward_select_conversation_key";
|
||||
public static final int FORWARD_SELECT_ACTIVTY_CODE = 101;
|
||||
public static final String FORWARD_CREATE_NEW_CHAT = "forward_create_new_chat";
|
||||
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_KEY = "conversationGroupChangeKey";
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_ADD = "conversationGroupChangeAdd";
|
||||
public static final String EVENT_CONVERSATION_GROUP_ADD_DATA = "conversationGroupAddData";
|
||||
public static final String EVENT_CONVERSATION_GROUP_ADD_MARK_DATA = "conversationGroupAddMarkData";
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_DELETE = "conversationGroupChangeDelete";
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_RENAME = "conversationGroupChangeRename";
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_GROUP_NAME = "conversationGroupChangeGroupname";
|
||||
public static final String EVENT_CONVERSATION_GROUP_CHANGE_UNREAD_COUNT = "conversationGroupChangeUnreadCount";
|
||||
|
||||
public static final String CONVERSATION_MARK_NAME_KEY = "conversationMarkNameKey";
|
||||
public static final String CONVERSATION_GROUP_NAME_KEY = "conversationGroupNameKey";
|
||||
public static final String CONVERSATION_MARK_DATA_REFRESH_KEY = "conversationMarkDataRefreshKey";
|
||||
public static final String CONVERSATION_MARK_DATA_REFRESH_SUBKEY = "conversationMarkDataRefreshSubKey";
|
||||
public static final String CONVERSATION_MARK_DATA_REFRESH_VALUE = "conversationMarkDataRefreshValue";
|
||||
|
||||
public static final String CONVERSATION_ALL_GROUP_UNREAD_CHANGE_BY_DIFF = "conversationAllGroupUnreadChangeByDiff";
|
||||
public static final String CONVERSATION_ALL_GROUP_UNREAD_DIFF = "conversationAllGroupUnreadDiff";
|
||||
|
||||
public static class GroupType {
|
||||
public static final String TYPE = "type";
|
||||
public static final String GROUP = "isGroup";
|
||||
public static final int PRIVATE = 0;
|
||||
public static final int PUBLIC = 1;
|
||||
public static final int CHAT_ROOM = 2;
|
||||
public static final int COMMUNITY = 3;
|
||||
}
|
||||
|
||||
public static final String CONVERSATION_SETTINGS_SP_NAME = "conversation_settings_sp";
|
||||
public static final String HIDE_FOLD_ITEM_SP_KEY_PREFIX = "hide_fold_item_";
|
||||
public static final String FOLD_ITEM_IS_UNREAD_SP_KEY_PREFIX = "fold_item_is_unread_";
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListener;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMSDKListener;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.ServiceInitializer;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.annotations.TUIInitializerDependency;
|
||||
import com.tencent.qcloud.tuicore.annotations.TUIInitializerID;
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUINotification;
|
||||
import com.tencent.qcloud.tuicore.interfaces.ITUIService;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIInitializer;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationGroupBean;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationEventListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationGroupNotifyListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@AutoService(TUIInitializer.class)
|
||||
@TUIInitializerDependency("TIMCommon")
|
||||
@TUIInitializerID("TUIConversation")
|
||||
public class TUIConversationService implements TUIInitializer, ITUIService, ITUINotification {
|
||||
public static final String TAG = TUIConversationService.class.getSimpleName();
|
||||
private static TUIConversationService instance;
|
||||
|
||||
public static TUIConversationService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private boolean syncFinished = false;
|
||||
|
||||
private final List<SoftReference<ConversationEventListener>> conversationEventListenerList = new ArrayList<>();
|
||||
private SoftReference<ConversationGroupNotifyListener> conversationGroupNotifyListener;
|
||||
private int conversationAllGroupUnreadDiff = 0;
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
instance = this;
|
||||
initTheme();
|
||||
initService();
|
||||
initEvent();
|
||||
initIMListener();
|
||||
}
|
||||
|
||||
private void initTheme() {
|
||||
TUIThemeManager.addLightTheme(R.style.TUIConversationLightTheme);
|
||||
TUIThemeManager.addLivelyTheme(R.style.TUIConversationLivelyTheme);
|
||||
TUIThemeManager.addSeriousTheme(R.style.TUIConversationSeriousTheme);
|
||||
}
|
||||
|
||||
private void initService() {
|
||||
TUICore.registerService(TUIConstants.TUIConversation.SERVICE_NAME, this);
|
||||
}
|
||||
|
||||
private void initEvent() {
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_GROUP, TUIConstants.TUIContact.EVENT_SUB_KEY_EXIT_GROUP, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_GROUP, TUIConstants.TUIContact.EVENT_SUB_KEY_MEMBER_KICKED_GROUP, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_GROUP, TUIConstants.TUIContact.EVENT_SUB_KEY_GROUP_DISMISS, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_GROUP, TUIConstants.TUIContact.EVENT_SUB_KEY_GROUP_RECYCLE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED, TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_GROUP, TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_GROUP_MESSAGE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIContact.EVENT_USER, TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_C2C_MESSAGE, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIChat.EVENT_KEY_RECEIVE_MESSAGE, TUIConstants.TUIChat.EVENT_SUB_KEY_CONVERSATION_ID, this);
|
||||
TUICore.registerEvent(TUIConstants.TUIConversation.EVENT_KEY_MESSAGE_SEND_FOR_CONVERSATION,
|
||||
TUIConstants.TUIConversation.EVENT_SUB_KEY_MESSAGE_SEND_FOR_CONVERSATION, this);
|
||||
TUICore.registerEvent(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_DATA, this);
|
||||
TUICore.registerEvent(
|
||||
TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_MARK_DATA, this);
|
||||
TUICore.registerEvent(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_ADD, this);
|
||||
TUICore.registerEvent(
|
||||
TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_DELETE, this);
|
||||
TUICore.registerEvent(
|
||||
TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_RENAME, this);
|
||||
TUICore.registerEvent(
|
||||
TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_UNREAD_COUNT, this);
|
||||
TUICore.registerEvent(
|
||||
TUIConstants.TUIChat.Event.MessageDisplayString.KEY, TUIConstants.TUIChat.Event.MessageDisplayString.SUB_KEY_PROCESS_MESSAGE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onCall(String method, Map<String, Object> param) {
|
||||
Bundle result = new Bundle();
|
||||
|
||||
if (TextUtils.equals(method, TUIConversationConstants.CONVERSATION_ALL_GROUP_UNREAD_CHANGE_BY_DIFF)) {
|
||||
if (param == null) {
|
||||
return result;
|
||||
}
|
||||
ConversationEventListener eventListener = getConversationEventListener();
|
||||
if (eventListener != null) {
|
||||
int diff = (int) param.get(TUIConversationConstants.CONVERSATION_ALL_GROUP_UNREAD_DIFF);
|
||||
int count = conversationAllGroupUnreadDiff + diff;
|
||||
ConversationPresenter presenter = new ConversationPresenter();
|
||||
presenter.updateUnreadTotalByDiff(count);
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_IS_TOP_CONVERSATION, method)) {
|
||||
ConversationEventListener conversationEventListener = getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
String chatId = (String) param.get(TUIConstants.TUIConversation.CHAT_ID);
|
||||
if (!TextUtils.isEmpty(chatId)) {
|
||||
boolean isTop = conversationEventListener.isTopConversation(chatId);
|
||||
result.putBoolean(TUIConstants.TUIConversation.IS_TOP, isTop);
|
||||
}
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_SET_TOP_CONVERSATION, method)) {
|
||||
ConversationEventListener conversationEventListener = getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
String chatId = (String) param.get(TUIConstants.TUIConversation.CHAT_ID);
|
||||
boolean isTop = (boolean) param.get(TUIConstants.TUIConversation.IS_SET_TOP);
|
||||
if (!TextUtils.isEmpty(chatId)) {
|
||||
conversationEventListener.setConversationTop(chatId, isTop, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_GET_TOTAL_UNREAD_COUNT, method)) {
|
||||
ConversationEventListener conversationEventListener = getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
return conversationEventListener.getUnreadTotal();
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_UPDATE_TOTAL_UNREAD_COUNT, method)) {
|
||||
ConversationEventListener conversationEventListener = getConversationEventListener();
|
||||
if (conversationEventListener != null) {
|
||||
HashMap<String, Object> unreadMap = new HashMap<>();
|
||||
long totalUnread = conversationEventListener.getUnreadTotal();
|
||||
unreadMap.put(TUIConstants.TUIConversation.TOTAL_UNREAD_COUNT, totalUnread);
|
||||
TUICore.notifyEvent(TUIConstants.TUIConversation.EVENT_UNREAD, TUIConstants.TUIConversation.EVENT_SUB_KEY_UNREAD_CHANGED, unreadMap);
|
||||
}
|
||||
} else if (TextUtils.equals(TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION, method)) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
String conversationId = (String) param.get(TUIConstants.TUIConversation.CONVERSATION_ID);
|
||||
conversationEventObserver.clearFoldMarkAndDeleteConversation(conversationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyEvent(String key, String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(key, TUIConstants.TUIContact.EVENT_GROUP)) {
|
||||
handleGroupEvent(subKey, param);
|
||||
} else if (key.equals(TUIConstants.TUIContact.EVENT_USER)) {
|
||||
handleContactUserEvent(subKey, param);
|
||||
} else if (key.equals(TUIConstants.TUIContact.EVENT_FRIEND_INFO_CHANGED)) {
|
||||
handleFriendInfoChangedEvent(subKey, param);
|
||||
} else if (key.equals(TUIConstants.TUIChat.EVENT_KEY_RECEIVE_MESSAGE)) {
|
||||
handleChatReceiveMessageEvent(subKey, param);
|
||||
} else if (TextUtils.equals(key, TUIConstants.TUIConversation.EVENT_KEY_MESSAGE_SEND_FOR_CONVERSATION)) {
|
||||
handleConversationEvent(subKey, param);
|
||||
} else if (TextUtils.equals(key, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_KEY)) {
|
||||
handleConversationGroupChangedEvent(subKey, param);
|
||||
} else if (TextUtils.equals(key, TUIConstants.TUIChat.Event.MessageDisplayString.KEY)) {
|
||||
handleMessageBeanUpdateEvent(subKey, param);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleConversationEvent(String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(subKey, TUIConstants.TUIConversation.EVENT_SUB_KEY_MESSAGE_SEND_FOR_CONVERSATION)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String conversationID = (String) param.get(TUIConstants.TUIConversation.CONVERSATION_ID);
|
||||
List<ConversationEventListener> conversationEventListenerList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventListener : conversationEventListenerList) {
|
||||
if (conversationEventListener != null) {
|
||||
conversationEventListener.onMessageSendForHideConversation(conversationID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleConversationGroupChangedEvent(String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_ADD)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_CHANGE_ADD param is null");
|
||||
return;
|
||||
}
|
||||
ConversationGroupBean bean = (ConversationGroupBean) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_ADD);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyGroupAdd(bean);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_DATA)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_ADD_DATA param is null");
|
||||
return;
|
||||
}
|
||||
List<ConversationGroupBean> beans = (List<ConversationGroupBean>) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_DATA);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyGroupsAdd(beans);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_MARK_DATA)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_ADD_MARK_DATA param is null");
|
||||
return;
|
||||
}
|
||||
List<ConversationGroupBean> beans = (List<ConversationGroupBean>) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_ADD_MARK_DATA);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyMarkGroupsAdd(beans);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_DELETE)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_CHANGE_DELETE param is null");
|
||||
return;
|
||||
}
|
||||
String groupName = (String) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_DELETE);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyGroupDelete(groupName);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_RENAME)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_CHANGE_RENAME param is null");
|
||||
return;
|
||||
}
|
||||
String oldName = (String) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_RENAME);
|
||||
String newName = (String) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_GROUP_NAME);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyGroupRename(oldName, newName);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_UNREAD_COUNT)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
TUIConversationLog.e(TAG, "EVENT_CONVERSATION_GROUP_CHANGE_UNREAD_COUNT param is null");
|
||||
return;
|
||||
}
|
||||
long count = (long) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_UNREAD_COUNT);
|
||||
String groupName = (String) param.get(TUIConversationConstants.EVENT_CONVERSATION_GROUP_CHANGE_GROUP_NAME);
|
||||
ConversationGroupNotifyListener eventListener = getConversationGroupNotifyListener();
|
||||
if (eventListener != null) {
|
||||
eventListener.notifyGroupUnreadMessageCountChanged(groupName, count);
|
||||
} else {
|
||||
TUIConversationLog.e(TAG, "eventListener is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ConversationEventListener getConversationEventListener() {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
if (!conversationEventObserverList.isEmpty()) {
|
||||
return conversationEventObserverList.get(0);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleChatReceiveMessageEvent(String subKey, Map<String, Object> param) {
|
||||
if (subKey.equals(TUIConstants.TUIChat.EVENT_SUB_KEY_CONVERSATION_ID)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String conversationID = (String) param.get(TUIConstants.TUIChat.CONVERSATION_ID);
|
||||
boolean isTypingMessage = false;
|
||||
if (param.containsKey(TUIConstants.TUIChat.IS_TYPING_MESSAGE)) {
|
||||
isTypingMessage = (Boolean) param.get(TUIConstants.TUIChat.IS_TYPING_MESSAGE);
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.onReceiveMessage(conversationID, isTypingMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFriendInfoChangedEvent(String subKey, Map<String, Object> param) {
|
||||
if (subKey.equals(TUIConstants.TUIContact.EVENT_SUB_KEY_FRIEND_REMARK_CHANGED)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String id = (String) param.get(TUIConstants.TUIContact.FRIEND_ID);
|
||||
String remark = (String) param.get(TUIConstants.TUIContact.FRIEND_REMARK);
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.onFriendRemarkChanged(id, remark);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleContactUserEvent(String subKey, Map<String, Object> param) {
|
||||
if (subKey.equals(TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_C2C_MESSAGE)) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String userID = (String) getOrDefault(param.get(TUIConstants.TUIContact.FRIEND_ID), "");
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.clearConversationMessage(userID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGroupEvent(String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(subKey, TUIConstants.TUIContact.EVENT_SUB_KEY_EXIT_GROUP)
|
||||
|| TextUtils.equals(subKey, TUIConstants.TUIContact.EVENT_SUB_KEY_GROUP_DISMISS)
|
||||
|| TextUtils.equals(subKey, TUIConstants.TUIContact.EVENT_SUB_KEY_GROUP_RECYCLE)) {
|
||||
String groupId = null;
|
||||
if (param != null) {
|
||||
groupId = (String) getOrDefault(param.get(TUIConstants.TUIContact.GROUP_ID), "");
|
||||
}
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.deleteConversation(groupId, true);
|
||||
}
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConstants.TUIContact.EVENT_SUB_KEY_MEMBER_KICKED_GROUP)) {
|
||||
if (param == null) {
|
||||
return;
|
||||
}
|
||||
String groupId = (String) getOrDefault(param.get(TUIConstants.TUIContact.GROUP_ID), "");
|
||||
ArrayList<String> memberList = (ArrayList<String>) param.get(TUIConstants.TUIContact.GROUP_MEMBER_ID_LIST);
|
||||
if (TextUtils.isEmpty(groupId) || memberList == null || memberList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String id : memberList) {
|
||||
if (TextUtils.equals(id, TUILogin.getLoginUser())) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.deleteConversation(groupId, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (TextUtils.equals(subKey, TUIConstants.TUIContact.EVENT_SUB_KEY_CLEAR_GROUP_MESSAGE)) {
|
||||
String groupId = (String) getOrDefault(param.get(TUIConstants.TUIContact.GROUP_ID), "");
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.clearConversationMessage(groupId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessageBeanUpdateEvent(String subKey, Map<String, Object> param) {
|
||||
if (TextUtils.equals(TUIConstants.TUIChat.Event.MessageDisplayString.SUB_KEY_PROCESS_MESSAGE, subKey)) {
|
||||
String conversationID = (String) param.get(TUIConstants.TUIChat.Event.MessageDisplayString.CONVERSATION_ID);
|
||||
TUIMessageBean messageBean = (TUIMessageBean) param.get(TUIConstants.TUIChat.Event.MessageDisplayString.MESSAGE_BEAN);
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.onConversationLastMessageBeanChanged(conversationID, messageBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object getOrDefault(Object value, Object defaultValue) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private void initIMListener() {
|
||||
V2TIMManager.getConversationManager().addConversationListener(new V2TIMConversationListener() {
|
||||
@Override
|
||||
public void onSyncServerStart() {
|
||||
syncFinished = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFinish() {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.onSyncServerFinish();
|
||||
}
|
||||
}
|
||||
|
||||
syncFinished = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFailed() {
|
||||
syncFinished = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewConversation(List<V2TIMConversation> conversationList) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
conversationEventObserver.onNewConversation(conversationInfoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<V2TIMConversation> conversationList) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
conversationEventObserver.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.updateTotalUnreadMessageCount(totalUnreadCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationDeleted(List<String> conversationIDList) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
if (conversationEventObserver != null) {
|
||||
conversationEventObserver.onConversationDeleted(conversationIDList);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
V2TIMSDKListener v2TIMSDKListener = new V2TIMSDKListener() {
|
||||
@Override
|
||||
public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {
|
||||
List<ConversationEventListener> conversationEventObserverList = getConversationEventListenerList();
|
||||
for (ConversationEventListener conversationEventObserver : conversationEventObserverList) {
|
||||
conversationEventObserver.onUserStatusChanged(userStatusList);
|
||||
}
|
||||
}
|
||||
};
|
||||
V2TIMManager.getInstance().addIMSDKListener(v2TIMSDKListener);
|
||||
}
|
||||
|
||||
public void addConversationEventListener(ConversationEventListener conversationEventListener) {
|
||||
if (conversationEventListener == null) {
|
||||
return;
|
||||
}
|
||||
for (SoftReference<ConversationEventListener> listenerWeakReference : conversationEventListenerList) {
|
||||
if (listenerWeakReference.get() == conversationEventListener) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
conversationEventListenerList.add(new SoftReference<>(conversationEventListener));
|
||||
}
|
||||
|
||||
public void removeConversationEventListener(ConversationEventListener conversationEventListener) {
|
||||
if (conversationEventListener == null) {
|
||||
return;
|
||||
}
|
||||
for (SoftReference<ConversationEventListener> listenerWeakReference : conversationEventListenerList) {
|
||||
if (listenerWeakReference.get() == conversationEventListener) {
|
||||
conversationEventListenerList.remove(listenerWeakReference);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConversationEventListener> getConversationEventListenerList() {
|
||||
List<ConversationEventListener> listeners = new ArrayList<>();
|
||||
Iterator<SoftReference<ConversationEventListener>> iterator = conversationEventListenerList.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
SoftReference<ConversationEventListener> listenerWeakReference = iterator.next();
|
||||
ConversationEventListener listener = listenerWeakReference.get();
|
||||
if (listener == null) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public void setConversationGroupNotifyListener(ConversationGroupNotifyListener listener) {
|
||||
this.conversationGroupNotifyListener = new SoftReference<>(listener);
|
||||
}
|
||||
|
||||
public ConversationGroupNotifyListener getConversationGroupNotifyListener() {
|
||||
if (conversationGroupNotifyListener != null) {
|
||||
return conversationGroupNotifyListener.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setConversationGroupNotifyListenerNull() {
|
||||
this.conversationGroupNotifyListener = null;
|
||||
}
|
||||
|
||||
public void setConversationAllGroupUnreadDiff(int diff) {
|
||||
this.conversationAllGroupUnreadDiff = diff;
|
||||
}
|
||||
|
||||
public static Context getAppContext() {
|
||||
return ServiceInitializer.getAppContext();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
public class ConversationGroupBean {
|
||||
public static final int CONVERSATION_GROUP_TYPE_DEFAULT = 101;
|
||||
public static final int CONVERSATION_GROUP_TYPE_MARK = 102;
|
||||
public static final int CONVERSATION_GROUP_TYPE_GROUP = 103;
|
||||
|
||||
public static final int CONVERSATION_ALL_GROUP_WEIGHT = 0;
|
||||
public static final int CONVERSATION_DEFAULT_GROUP_WEIGHT = 2;
|
||||
public static final int CONVERSATION_MARK_START_GROUP_WEIGHT = 4;
|
||||
public static final int CONVERSATION_GROUP_START_GROUP_WEIGHT = 5;
|
||||
|
||||
private transient String title;
|
||||
private int weight = 0;
|
||||
private boolean isHide;
|
||||
private transient int groupType;
|
||||
private transient long unReadCount;
|
||||
private transient long markType = -1;
|
||||
|
||||
public long getUnReadCount() {
|
||||
return unReadCount;
|
||||
}
|
||||
|
||||
public void setUnReadCount(long unReadCount) {
|
||||
this.unReadCount = unReadCount;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public long getMarkType() {
|
||||
return markType;
|
||||
}
|
||||
|
||||
public void setMarkType(long markType) {
|
||||
this.markType = markType;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public int getGroupType() {
|
||||
return groupType;
|
||||
}
|
||||
|
||||
public void setGroupType(int groupType) {
|
||||
this.groupType = groupType;
|
||||
}
|
||||
|
||||
public boolean getIsHide() {
|
||||
return isHide;
|
||||
}
|
||||
|
||||
public void setIsHide(boolean head) {
|
||||
this.isHide = head;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ConversationGroupBean bean = (ConversationGroupBean) o;
|
||||
// return Objects.equals(title, bean.title);
|
||||
return beanEquals(title, bean.title);
|
||||
}
|
||||
|
||||
private boolean beanEquals(Object a, Object b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// return Objects.hash(title);
|
||||
int result = 17;
|
||||
result = 31 * result + ((title == null) ? 0 : title.hashCode());
|
||||
result = 31 * result + (int) unReadCount;
|
||||
result = 31 * result + (int) markType;
|
||||
result = 31 * result + weight;
|
||||
result = 31 * result + groupType;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConversationGroupBean{"
|
||||
+ "title=" + title + ", unReadCount=" + unReadCount + ", markType='" + markType + '\'' + ", weight='" + weight + '\'' + ", groupType='" + groupType
|
||||
+ '\'' + ", isHide='" + isHide + '\'' + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupAtInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationInfo implements Serializable, Comparable<ConversationInfo> {
|
||||
public static final int TYPE_COMMON = 1;
|
||||
public static final int TYPE_CUSTOM = 2;
|
||||
|
||||
public static final int TYPE_FORWAR_SELECT = 3;
|
||||
public static final int TYPE_RECENT_LABEL = 4;
|
||||
|
||||
public static final int AT_TYPE_AT_ME = V2TIMGroupAtInfo.TIM_AT_ME;
|
||||
public static final int AT_TYPE_AT_ALL = V2TIMGroupAtInfo.TIM_AT_ALL;
|
||||
public static final int AT_TYPE_AT_ALL_AND_ME = V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME;
|
||||
public static final int AT_TYPE_UNKNOWN = V2TIMGroupAtInfo.TIM_AT_UNKNOWN;
|
||||
|
||||
public static final int USER_STATUS_UNKNOWN = V2TIMUserStatus.V2TIM_USER_STATUS_UNKNOWN;
|
||||
public static final int USER_STATUS_ONLINE = V2TIMUserStatus.V2TIM_USER_STATUS_ONLINE;
|
||||
|
||||
public static final int LAST_MSG_STATUS_UNKNOWN = 0;
|
||||
public static final int LAST_MSG_STATUS_SENDING = V2TIMMessage.V2TIM_MSG_STATUS_SENDING;
|
||||
public static final int LAST_MSG_STATUS_SEND_FAIL = V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL;
|
||||
public static final int LAST_MSG_STATUS_HAS_DELETED = V2TIMMessage.V2TIM_MSG_STATUS_HAS_DELETED;
|
||||
public static final int LAST_MSG_STATUS_LOCAL_IMPORTED = V2TIMMessage.V2TIM_MSG_STATUS_LOCAL_IMPORTED;
|
||||
public static final int LAST_MSG_STATUS_LOCAL_REVOKED = V2TIMMessage.V2TIM_MSG_STATUS_LOCAL_REVOKED;
|
||||
|
||||
/**
|
||||
* conversation type
|
||||
*/
|
||||
private int type;
|
||||
|
||||
private int atType = AT_TYPE_UNKNOWN;
|
||||
|
||||
/**
|
||||
* unread message number
|
||||
*/
|
||||
private int unRead;
|
||||
/**
|
||||
* conversation ID
|
||||
*/
|
||||
private String conversationId;
|
||||
/**
|
||||
* ID, C2C is UserID, Group is group ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
private int statusType = USER_STATUS_UNKNOWN;
|
||||
|
||||
private V2TIMConversation conversation;
|
||||
|
||||
private List<Object> iconUrlList = new ArrayList<>();
|
||||
|
||||
public List<Object> getIconUrlList() {
|
||||
return iconUrlList;
|
||||
}
|
||||
|
||||
public void setIconUrlList(List<Object> iconUrlList) {
|
||||
this.iconUrlList = iconUrlList;
|
||||
}
|
||||
|
||||
public V2TIMConversation getConversation() {
|
||||
return conversation;
|
||||
}
|
||||
|
||||
public void setConversation(V2TIMConversation conversation) {
|
||||
this.conversation = conversation;
|
||||
}
|
||||
|
||||
public String getShowName() {
|
||||
if (conversation != null) {
|
||||
return conversation.getShowName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String title;
|
||||
private String iconPath;
|
||||
private boolean isGroup;
|
||||
private boolean top;
|
||||
/**
|
||||
* Is folded conversation or not
|
||||
*/
|
||||
private boolean isMarkFold;
|
||||
/**
|
||||
* Is marked conversation unread or not
|
||||
*/
|
||||
private boolean isMarkUnread;
|
||||
/**
|
||||
* Is marked conversation hidden or not
|
||||
*/
|
||||
private boolean isMarkHidden;
|
||||
/**
|
||||
* Is marked conversation local-unread or not
|
||||
*/
|
||||
private boolean isMarkLocalUnread;
|
||||
|
||||
private boolean isMarkStar;
|
||||
|
||||
private long lastMessageTime;
|
||||
private V2TIMMessage lastMessage;
|
||||
|
||||
private TUIMessageBean lastTUIMessageBean;
|
||||
|
||||
/**
|
||||
* "@" message in group
|
||||
*/
|
||||
private String atInfoText;
|
||||
|
||||
/**
|
||||
* the conversation item displays the icon of Do Not Disturb
|
||||
*/
|
||||
private boolean showDisturbIcon;
|
||||
|
||||
private DraftInfo draft;
|
||||
private String groupType;
|
||||
|
||||
/**
|
||||
* conversation sort key
|
||||
*/
|
||||
private long orderKey;
|
||||
|
||||
public ConversationInfo() {}
|
||||
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
public void setConversationId(String conversationId) {
|
||||
this.conversationId = conversationId;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getUnRead() {
|
||||
return unRead;
|
||||
}
|
||||
|
||||
public void setUnRead(int unRead) {
|
||||
this.unRead = unRead;
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return isGroup;
|
||||
}
|
||||
|
||||
public void setGroup(boolean group) {
|
||||
isGroup = group;
|
||||
}
|
||||
|
||||
public boolean isTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
public void setTop(boolean top) {
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
public boolean isMarkFold() {
|
||||
return isMarkFold;
|
||||
}
|
||||
|
||||
public void setMarkFold(boolean markFold) {
|
||||
isMarkFold = markFold;
|
||||
}
|
||||
|
||||
public boolean isMarkUnread() {
|
||||
return isMarkUnread;
|
||||
}
|
||||
|
||||
public void setMarkUnread(boolean markUnread) {
|
||||
isMarkUnread = markUnread;
|
||||
}
|
||||
|
||||
public boolean isMarkHidden() {
|
||||
return isMarkHidden;
|
||||
}
|
||||
|
||||
public void setMarkHidden(boolean markHidden) {
|
||||
isMarkHidden = markHidden;
|
||||
}
|
||||
|
||||
public boolean isMarkLocalUnread() {
|
||||
return isMarkLocalUnread;
|
||||
}
|
||||
|
||||
public void setMarkLocalUnread(boolean markLocalUnread) {
|
||||
isMarkLocalUnread = markLocalUnread;
|
||||
}
|
||||
|
||||
public boolean isMarkStar() {
|
||||
return isMarkStar;
|
||||
}
|
||||
|
||||
public void setMarkStar(boolean markStar) {
|
||||
isMarkStar = markStar;
|
||||
}
|
||||
|
||||
public List<Long> getMarkList() {
|
||||
if (conversation == null) {
|
||||
return null;
|
||||
}
|
||||
return conversation.getMarkList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time of the last message, in seconds
|
||||
*/
|
||||
public long getLastMessageTime() {
|
||||
return lastMessageTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time of the last message, in seconds
|
||||
* @param lastMessageTime
|
||||
*/
|
||||
public void setLastMessageTime(long lastMessageTime) {
|
||||
this.lastMessageTime = lastMessageTime;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setAtType(int atType) {
|
||||
this.atType = atType;
|
||||
}
|
||||
|
||||
public int getAtType() {
|
||||
return atType;
|
||||
}
|
||||
|
||||
public V2TIMMessage getLastMessage() {
|
||||
return lastMessage;
|
||||
}
|
||||
|
||||
public void setLastMessage(V2TIMMessage lastMessage) {
|
||||
this.lastMessage = lastMessage;
|
||||
}
|
||||
|
||||
public void setAtInfoText(String atInfoText) {
|
||||
this.atInfoText = atInfoText;
|
||||
}
|
||||
|
||||
public String getAtInfoText() {
|
||||
return atInfoText;
|
||||
}
|
||||
|
||||
public boolean isShowDisturbIcon() {
|
||||
return showDisturbIcon;
|
||||
}
|
||||
|
||||
public void setShowDisturbIcon(boolean showDisturbIcon) {
|
||||
this.showDisturbIcon = showDisturbIcon;
|
||||
}
|
||||
|
||||
public void setDraft(DraftInfo draft) {
|
||||
this.draft = draft;
|
||||
}
|
||||
|
||||
public DraftInfo getDraft() {
|
||||
return this.draft;
|
||||
}
|
||||
|
||||
public String getGroupType() {
|
||||
return groupType;
|
||||
}
|
||||
|
||||
public void setGroupType(String groupType) {
|
||||
this.groupType = groupType;
|
||||
}
|
||||
|
||||
public String getIconPath() {
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
public void setIconPath(String iconPath) {
|
||||
this.iconPath = iconPath;
|
||||
}
|
||||
|
||||
public void setOrderKey(long orderKey) {
|
||||
this.orderKey = orderKey;
|
||||
}
|
||||
|
||||
public long getOrderKey() {
|
||||
return orderKey;
|
||||
}
|
||||
|
||||
public List<V2TIMGroupAtInfo> getGroupAtInfoList() {
|
||||
if (conversation != null) {
|
||||
return conversation.getGroupAtInfoList();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStatusType() {
|
||||
return statusType;
|
||||
}
|
||||
|
||||
public void setStatusType(int statusType) {
|
||||
this.statusType = statusType;
|
||||
}
|
||||
|
||||
public List<String> getConversationGroupList() {
|
||||
if (conversation != null) {
|
||||
return conversation.getConversationGroupList();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getLastMessageStatus() {
|
||||
if (conversation != null) {
|
||||
if (conversation.getLastMessage() != null) {
|
||||
return conversation.getLastMessage().getStatus();
|
||||
}
|
||||
}
|
||||
return LAST_MSG_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
public TUIMessageBean getLastTUIMessageBean() {
|
||||
return lastTUIMessageBean;
|
||||
}
|
||||
|
||||
public void setLastTUIMessageBean(TUIMessageBean lastTUIMessageBean) {
|
||||
this.lastTUIMessageBean = lastTUIMessageBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull ConversationInfo other) {
|
||||
if (this.isTop() && !other.isTop()) {
|
||||
return -1;
|
||||
} else if (!this.isTop() && other.isTop()) {
|
||||
return 1;
|
||||
} else {
|
||||
long thisOrderKey = this.orderKey;
|
||||
long otherOrderKey = other.orderKey;
|
||||
if (thisOrderKey > otherOrderKey) {
|
||||
return -1;
|
||||
} else if (thisOrderKey == otherOrderKey) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConversationInfo{"
|
||||
+ "type=" + type + ", unRead=" + unRead + ", conversationId='" + conversationId + '\'' + ", id='" + id + '\'' + ", iconUrl='" + iconUrlList.size()
|
||||
+ '\'' + ", title='" + title + '\'' + ", iconPath=" + iconPath + ", isGroup=" + isGroup + ", top=" + top + ", lastMessageTime=" + lastMessageTime
|
||||
+ ", lastMessage=" + lastMessage + ", draftText=" + draft + ", groupType=" + groupType + ", statusType=" + statusType + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public class ConversationPopMenuItem {
|
||||
public String text;
|
||||
public int iconResId;
|
||||
public boolean isAlert;
|
||||
public View.OnClickListener onClickListener;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
|
||||
public class ConversationUserStatusBean {
|
||||
|
||||
public static final int USER_STATUS_UNKNOWN = V2TIMUserStatus.V2TIM_USER_STATUS_UNKNOWN;
|
||||
public static final int USER_STATUS_ONLINE = V2TIMUserStatus.V2TIM_USER_STATUS_ONLINE;
|
||||
public static final int USER_STATUS_OFFLINE = V2TIMUserStatus.V2TIM_USER_STATUS_OFFLINE;
|
||||
public static final int USER_STATUS_UNLOGINED = V2TIMUserStatus.V2TIM_USER_STATUS_UNLOGINED;
|
||||
|
||||
private V2TIMUserStatus v2TIMUserStatus;
|
||||
|
||||
public void setV2TIMUserStatus(V2TIMUserStatus v2TIMUserStatus) {
|
||||
this.v2TIMUserStatus = v2TIMUserStatus;
|
||||
}
|
||||
|
||||
public String getUserID() {
|
||||
if (v2TIMUserStatus != null) {
|
||||
return v2TIMUserStatus.getUserID();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public int getStatusType() {
|
||||
if (v2TIMUserStatus != null) {
|
||||
return v2TIMUserStatus.getStatusType();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class DraftInfo implements Serializable {
|
||||
private String draftText;
|
||||
private long draftTime;
|
||||
|
||||
public String getDraftText() {
|
||||
return draftText;
|
||||
}
|
||||
|
||||
public void setDraftText(String draftText) {
|
||||
this.draftText = draftText;
|
||||
}
|
||||
|
||||
public long getDraftTime() {
|
||||
return draftTime;
|
||||
}
|
||||
|
||||
public void setDraftTime(long draftTime) {
|
||||
this.draftTime = draftTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DraftInfo{"
|
||||
+ "draftText='" + draftText + '\'' + ", draftTime=" + draftTime + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.ILayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public interface IConversationLayout extends ILayout {
|
||||
View getConversationList();
|
||||
|
||||
void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack);
|
||||
|
||||
void deleteConversation(ConversationInfo conversation);
|
||||
|
||||
void clearConversationMessage(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* Hide normal conversation
|
||||
*/
|
||||
void markConversationHidden(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* Mark conversation read or unread
|
||||
*/
|
||||
void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread);
|
||||
|
||||
/**
|
||||
* Hide folded conversation item
|
||||
*/
|
||||
void hideFoldedItem(boolean needHide);
|
||||
|
||||
/**
|
||||
* Clear unread status of fold item
|
||||
*/
|
||||
void clearUnreadStatusOfFoldItem();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
public interface IConversationListLayout {
|
||||
void setBackground(int resId);
|
||||
|
||||
void setOnConversationAdapterListener(OnConversationAdapterListener listener);
|
||||
|
||||
/**
|
||||
* Do not display the switch for the number of unread messages with the small red dot
|
||||
*
|
||||
* @param flag false,
|
||||
*/
|
||||
void disableItemUnreadDot(boolean flag);
|
||||
|
||||
View getListLayout();
|
||||
|
||||
ConversationListAdapter getAdapter();
|
||||
|
||||
void setAdapter(IConversationListAdapter adapter);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IConversationProvider {
|
||||
/**
|
||||
* Get a specific session data set, and ConversationContainer displays the session list based on the data set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ConversationInfo> getDataSource();
|
||||
|
||||
/**
|
||||
* Bulk add session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean addConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Delete session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean deleteConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Update session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean updateConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Called when a session adapter is bound, automatically called when {@link
|
||||
* com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider} is called
|
||||
*/
|
||||
|
||||
void attachAdapter(IConversationListAdapter adapter);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OnConversationAdapterListener {
|
||||
void onItemClick(View view, int viewType, ConversationInfo conversationInfo);
|
||||
|
||||
void onItemLongClick(View view, ConversationInfo conversationInfo);
|
||||
|
||||
void onConversationChanged(List<ConversationInfo> dataSource);
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIExtensionEventListener;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIExtensionInfo;
|
||||
import com.tencent.qcloud.tuicore.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.dialog.TUIKitDialog;
|
||||
import com.tencent.qcloud.tuikit.timcommon.config.classicui.TUIConfigClassic;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.LayoutUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationGroupBean;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.classicui.TUIConversationConfigClassic;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIConversationFragment extends Fragment {
|
||||
private static final String TAG = TUIConversationFragment.class.getSimpleName();
|
||||
|
||||
private View mBaseView;
|
||||
private ConversationLayout mConversationLayout;
|
||||
private ListView mConversationPopList;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
TUIConversationLog.d(TAG, "onCreateView");
|
||||
mBaseView = inflater.inflate(R.layout.conversation_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
presenter.setFocus(true);
|
||||
TUIConversationLog.d(TAG, "onResume");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
presenter.setFocus(false);
|
||||
TUIConversationLog.d(TAG, "onPause");
|
||||
}
|
||||
|
||||
public static TUIConversationFragment newInstance() {
|
||||
TUIConversationFragment fragment = new TUIConversationFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
|
||||
mConversationLayout = mBaseView.findViewById(R.id.conversation_layout);
|
||||
TUIConfigClassic.setMessageListAvatarSize(100);
|
||||
TUIConfigClassic.setMessageListAvatarRadius(50);
|
||||
presenter = new ConversationPresenter();
|
||||
presenter.setConversationListener();
|
||||
presenter.setShowType(ConversationPresenter.SHOW_TYPE_CONVERSATION_LIST_WITH_FOLD);
|
||||
presenter.setConversationGroupType(ConversationGroupBean.CONVERSATION_GROUP_TYPE_DEFAULT);
|
||||
mConversationLayout.setPresenter(presenter);
|
||||
|
||||
mConversationLayout.initDefault();
|
||||
|
||||
mConversationLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.clearUnreadStatusOfFoldItem();
|
||||
startFoldedConversationActivity();
|
||||
} else {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
return;
|
||||
}
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
public void restoreConversationItemBackground() {
|
||||
if (mConversationLayout.getConversationList().getAdapter() != null && mConversationLayout.getConversationList().getAdapter().isClick()) {
|
||||
mConversationLayout.getConversationList().getAdapter().setClick(false);
|
||||
mConversationLayout.getConversationList().getAdapter().notifyItemChanged(
|
||||
mConversationLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private PopMenuAction getMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction markUnreadAction = new PopMenuAction();
|
||||
markUnreadAction.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mConversationLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
markUnreadAction.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
markUnreadAction.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
markUnreadAction.setWeight(900);
|
||||
return markUnreadAction;
|
||||
}
|
||||
|
||||
private PopMenuAction getDeletePopMenuAction() {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
TUIKitDialog tipsDialog =
|
||||
new TUIKitDialog(getContext())
|
||||
.builder()
|
||||
.setCancelable(true)
|
||||
.setCancelOutside(true)
|
||||
.setTitle(getContext().getString(R.string.conversation_delete_tips))
|
||||
.setDialogWidth(0.75f)
|
||||
.setPositiveButton(getContext().getString(com.tencent.qcloud.tuicore.R.string.sure),
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(getContext().getString(com.tencent.qcloud.tuicore.R.string.cancel), new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {}
|
||||
});
|
||||
tipsDialog.show();
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
action.setWeight(700);
|
||||
return action;
|
||||
}
|
||||
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
mConversationPopActions.clear();
|
||||
|
||||
PopMenuAction hideAction = new PopMenuAction();
|
||||
hideAction.setActionName(getResources().getString(R.string.not_display));
|
||||
hideAction.setWeight(800);
|
||||
hideAction.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.hideFoldedItem(true);
|
||||
} else {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
mConversationPopActions.add(hideAction);
|
||||
|
||||
PopMenuAction markUnreadAction = null;
|
||||
PopMenuAction deleteAction = null;
|
||||
|
||||
if (!conversationInfo.isMarkFold()) {
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
markUnreadAction = getMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
markUnreadAction = getMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
markUnreadAction = getMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
deleteAction = getDeletePopMenuAction();
|
||||
mConversationPopActions.add(markUnreadAction);
|
||||
mConversationPopActions.add(deleteAction);
|
||||
mConversationPopActions.addAll(addMoreConversationAction(conversationInfo));
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
TUIConversationConfigClassic.ConversationMenuItemDataSource dataSource = TUIConversationConfigClassic.getConversationMenuItemDataSource();
|
||||
if (dataSource != null) {
|
||||
List<Integer> excludeList = dataSource.conversationShouldHideItemsInMoreMenu(conversationInfo);
|
||||
if (excludeList != null && !excludeList.isEmpty()) {
|
||||
if (excludeList.contains(TUIConversationConfigClassic.HIDE)) {
|
||||
mConversationPopActions.remove(hideAction);
|
||||
}
|
||||
if (excludeList.contains(TUIConversationConfigClassic.DELETE)) {
|
||||
mConversationPopActions.remove(deleteAction);
|
||||
}
|
||||
}
|
||||
List<PopMenuAction> conversationPopMenuItems = dataSource.conversationShouldAddNewItemsToMoreMenu(conversationInfo);
|
||||
if (conversationPopMenuItems != null && !conversationPopMenuItems.isEmpty()) {
|
||||
mConversationPopActions.addAll(conversationPopMenuItems);
|
||||
}
|
||||
}
|
||||
Collections.sort(mConversationPopActions, new Comparator<PopMenuAction>() {
|
||||
@Override
|
||||
public int compare(PopMenuAction o1, PopMenuAction o2) {
|
||||
return o2.getWeight() - o1.getWeight();
|
||||
}
|
||||
});
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
if (LayoutUtil.isRTL()) {
|
||||
x = -x;
|
||||
}
|
||||
int y = -view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mConversationLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
|
||||
private void startFoldedConversationActivity() {
|
||||
Intent intent = new Intent(getActivity(), TUIFoldedConversationActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
protected List<PopMenuAction> addMoreConversationAction(ConversationInfo conversationInfo) {
|
||||
List<PopMenuAction> settingsList = new ArrayList<>();
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONTEXT, getContext());
|
||||
param.put(TUIConstants.TUIConversation.KEY_CONVERSATION_INFO, conversationInfo);
|
||||
List<TUIExtensionInfo> extensionList = TUICore.getExtensionList(TUIConstants.TUIConversation.Extension.ConversationPopMenu.CLASSIC_EXTENSION_ID, param);
|
||||
for (TUIExtensionInfo extensionInfo : extensionList) {
|
||||
String text = extensionInfo.getText();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
TUIExtensionEventListener listener = extensionInfo.getExtensionListener();
|
||||
if (listener != null) {
|
||||
listener.onClicked(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
action.setWeight(extensionInfo.getWeight());
|
||||
action.setActionName(text);
|
||||
settingsList.add(action);
|
||||
}
|
||||
}
|
||||
|
||||
return settingsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
TUIConversationLog.d(TAG, "onDestroy");
|
||||
if (presenter != null) {
|
||||
presenter.destroy();
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIExtensionInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationGroupBean;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationTabLayoutMediator;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationGroupNotifyListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIConversationFragmentContainer extends Fragment {
|
||||
private static final String TAG = TUIConversationFragmentContainer.class.getSimpleName();
|
||||
private List<ConversationGroupBean> mConversationGroupBeans = new ArrayList<>();
|
||||
|
||||
private View mBaseView;
|
||||
private ViewGroup searchLayout;
|
||||
private ViewGroup mTabLayout;
|
||||
private TabLayout mConversationTabLayout;
|
||||
private ViewGroup mConversationGroupSettingLayout;
|
||||
private ViewPager2 mViewPager;
|
||||
private ConversationTabLayoutMediator mediator;
|
||||
private FragmentStateAdapter adapter;
|
||||
private ConversationGroupNotifyListener conversationGroupNotifyListener;
|
||||
|
||||
private int selectedColor;
|
||||
private int selectedPosition;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
TUIConversationLog.d(TAG, "onCreateView");
|
||||
mBaseView = inflater.inflate(R.layout.conversation_base_fragment, container, false);
|
||||
searchLayout = mBaseView.findViewById(R.id.conversation_search_layout);
|
||||
mTabLayout = mBaseView.findViewById(R.id.conversation_tab_layout);
|
||||
mConversationTabLayout = (TabLayout) mBaseView.findViewById(R.id.conversation_tabs);
|
||||
mConversationGroupSettingLayout = mBaseView.findViewById(R.id.conversation_group_setting);
|
||||
mViewPager = (ViewPager2) mBaseView.findViewById(R.id.converstion_viewpager);
|
||||
|
||||
initSearchView();
|
||||
initGroupView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private Fragment newConversationMarkFragment(ConversationGroupBean bean) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConversationConstants.CONVERSATION_MARK_NAME_KEY, bean.getMarkType());
|
||||
Object markFragment = TUICore.createObject(
|
||||
TUIConstants.TUIConversationMarkPlugin.OBJECT_FACTORY_NAME, TUIConstants.TUIConversationMarkPlugin.OBJECT_CONVERSATION_MARK_FRAGMENT, param);
|
||||
if (markFragment instanceof Fragment) {
|
||||
return (Fragment) markFragment;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Fragment newConversationGroupFragment(ConversationGroupBean bean) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConversationConstants.CONVERSATION_GROUP_NAME_KEY, bean.getTitle());
|
||||
Object groupFragment = TUICore.createObject(
|
||||
TUIConstants.TUIConversationGroupPlugin.OBJECT_FACTORY_NAME, TUIConstants.TUIConversationGroupPlugin.OBJECT_CONVERSATION_GROUP_FRAGMENT, param);
|
||||
if (groupFragment instanceof Fragment) {
|
||||
return (Fragment) groupFragment;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void refreshConversationGroupSort() {
|
||||
Collections.sort(mConversationGroupBeans, new Comparator<ConversationGroupBean>() {
|
||||
@Override
|
||||
public int compare(ConversationGroupBean o1, ConversationGroupBean o2) {
|
||||
return o1.getWeight() - o2.getWeight();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<ConversationGroupBean> getGroupExtensionMoreSettings() {
|
||||
List<ConversationGroupBean> groupBeanList = new ArrayList<>();
|
||||
List<TUIExtensionInfo> extensionList =
|
||||
TUICore.getExtensionList(TUIConstants.TUIConversation.Extension.ConversationGroupBean.CLASSIC_EXTENSION_ID, null);
|
||||
for (TUIExtensionInfo extensionInfo : extensionList) {
|
||||
Map<String, Object> paramMap = extensionInfo.getData();
|
||||
Object beanObjectList = paramMap.get(TUIConstants.TUIConversation.Extension.ConversationGroupBean.KEY_DATA);
|
||||
if (beanObjectList != null && beanObjectList instanceof List) {
|
||||
groupBeanList = (List<ConversationGroupBean>) beanObjectList;
|
||||
}
|
||||
}
|
||||
|
||||
return groupBeanList;
|
||||
}
|
||||
|
||||
private List<ConversationGroupBean> getMarkExtensionMoreSettings() {
|
||||
List<ConversationGroupBean> groupBeanList = new ArrayList<>();
|
||||
List<TUIExtensionInfo> extensionList =
|
||||
TUICore.getExtensionList(TUIConstants.TUIConversation.Extension.ConversationMarkBean.CLASSIC_EXTENSION_ID, null);
|
||||
for (TUIExtensionInfo extensionInfo : extensionList) {
|
||||
Map<String, Object> paramMap = extensionInfo.getData();
|
||||
Object beanObjectList = paramMap.get(TUIConstants.TUIConversation.Extension.ConversationMarkBean.KEY_DATA);
|
||||
if (beanObjectList != null && beanObjectList instanceof List) {
|
||||
groupBeanList = (List<ConversationGroupBean>) beanObjectList;
|
||||
}
|
||||
}
|
||||
|
||||
return groupBeanList;
|
||||
}
|
||||
|
||||
private void refreshGroupView(boolean hide) {
|
||||
if (hide) {
|
||||
mTabLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
mTabLayout.setVisibility(View.VISIBLE);
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversationGroupPlugin.CONTEXT, getContext());
|
||||
TUICore.raiseExtension(TUIConstants.TUIConversationGroupPlugin.EXTENSION_GROUP_SETTING_MENU, mConversationGroupSettingLayout, param);
|
||||
}
|
||||
}
|
||||
|
||||
private void initGroupView() {
|
||||
mConversationGroupBeans.clear();
|
||||
|
||||
List<ConversationGroupBean> groupBeanList = getGroupExtensionMoreSettings();
|
||||
List<ConversationGroupBean> markBeanList = getMarkExtensionMoreSettings();
|
||||
|
||||
if (groupBeanList != null && !groupBeanList.isEmpty()) {
|
||||
mConversationGroupBeans.addAll(groupBeanList);
|
||||
}
|
||||
|
||||
if (markBeanList != null && !markBeanList.isEmpty()) {
|
||||
mConversationGroupBeans.addAll(markBeanList);
|
||||
}
|
||||
|
||||
if (mConversationGroupBeans.isEmpty()) {
|
||||
refreshGroupView(true);
|
||||
} else {
|
||||
refreshGroupView(false);
|
||||
}
|
||||
|
||||
ConversationGroupBean bean = new ConversationGroupBean();
|
||||
bean.setTitle(getString(R.string.conversation_page_all));
|
||||
bean.setWeight(ConversationGroupBean.CONVERSATION_ALL_GROUP_WEIGHT);
|
||||
bean.setGroupType(ConversationGroupBean.CONVERSATION_GROUP_TYPE_DEFAULT);
|
||||
if (!mConversationGroupBeans.contains(bean)) {
|
||||
mConversationGroupBeans.add(bean);
|
||||
}
|
||||
|
||||
refreshConversationGroupSort();
|
||||
|
||||
mViewPager.setOffscreenPageLimit(3);
|
||||
|
||||
adapter = new FragmentStateAdapter(getChildFragmentManager(), getLifecycle()) {
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
ConversationGroupBean bean = mConversationGroupBeans.get(position);
|
||||
if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_DEFAULT) {
|
||||
return TUIConversationFragment.newInstance();
|
||||
} else if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_GROUP) {
|
||||
return newConversationGroupFragment(bean);
|
||||
} else if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_MARK) {
|
||||
return newConversationMarkFragment(bean);
|
||||
} else {
|
||||
return TUIConversationFragment.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mConversationGroupBeans.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return mConversationGroupBeans.get(position).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsItem(long itemId) {
|
||||
for (ConversationGroupBean bean : mConversationGroupBeans) {
|
||||
if (itemId == bean.hashCode()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
mViewPager.setAdapter(adapter);
|
||||
selectedPosition = 0;
|
||||
mViewPager.setCurrentItem(selectedPosition);
|
||||
mViewPager.registerOnPageChangeCallback(changeCallback);
|
||||
selectedColor = getResources().getColor(TUIThemeManager.getAttrResId(getContext(), R.attr.conversation_tab_selected));
|
||||
mConversationTabLayout.setTabTextColors(getResources().getColor(com.tencent.qcloud.tuikit.timcommon.R.color.black), selectedColor);
|
||||
adapter.notifyDataSetChanged();
|
||||
// mViewPager.setUserInputEnabled(false);
|
||||
mediator =
|
||||
new ConversationTabLayoutMediator(mConversationTabLayout, mViewPager, true, false, new ConversationTabLayoutMediator.TabConfigurationStrategy() {
|
||||
@Override
|
||||
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
|
||||
TUIConversationLog.d(TAG, "onConfigureTab position" + position);
|
||||
|
||||
View layoutView = LayoutInflater.from(getContext()).inflate(R.layout.conversation_group_tab_item, null, false);
|
||||
TextView titileView = layoutView.findViewById(R.id.tab_title);
|
||||
TextView unreadView = layoutView.findViewById(R.id.tab_unread);
|
||||
titileView.setText(mConversationGroupBeans.get(position).getTitle());
|
||||
long count = mConversationGroupBeans.get(position).getUnReadCount();
|
||||
if (count == 0) {
|
||||
unreadView.setText("");
|
||||
} else if (count > 99) {
|
||||
unreadView.setText("99+");
|
||||
} else {
|
||||
unreadView.setText(String.valueOf(count));
|
||||
}
|
||||
tab.setCustomView(layoutView);
|
||||
|
||||
if (position == selectedPosition) {
|
||||
titileView.setTextColor(selectedColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
mediator.attach();
|
||||
|
||||
conversationGroupNotifyListener = new ConversationGroupNotifyListener() {
|
||||
@Override
|
||||
public void notifyGroupsAdd(List<ConversationGroupBean> beans) {
|
||||
addRefreshData(beans, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyMarkGroupsAdd(List<ConversationGroupBean> beans) {
|
||||
addRefreshData(beans, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyGroupAdd(ConversationGroupBean bean) {
|
||||
TUIConversationLog.d(TAG, "notifyGroupAdd");
|
||||
if (!mConversationGroupBeans.contains(bean)) {
|
||||
mConversationGroupBeans.add(bean);
|
||||
if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_MARK) {
|
||||
refreshConversationGroupSort();
|
||||
adapter.notifyDataSetChanged();
|
||||
} else {
|
||||
int notifyIndex = mConversationGroupBeans.size() - 1;
|
||||
adapter.notifyItemInserted(notifyIndex);
|
||||
}
|
||||
} else {
|
||||
TUIConversationLog.d(TAG, "notifyGroupAdd contains groupName = " + bean.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyGroupDelete(String groupName) {
|
||||
TUIConversationLog.d(TAG, "notifyGroupDelete");
|
||||
ListIterator<ConversationGroupBean> iterator = mConversationGroupBeans.listIterator();
|
||||
int index = 0;
|
||||
while (iterator.hasNext()) {
|
||||
ConversationGroupBean next = iterator.next();
|
||||
if (next.getTitle().equals(groupName)) {
|
||||
iterator.remove();
|
||||
adapter.notifyItemRangeRemoved(index, 1);
|
||||
break;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyGroupRename(String oldName, String newName) {
|
||||
TUIConversationLog.d(TAG, "notifyGroupRename");
|
||||
ListIterator<ConversationGroupBean> iterator = mConversationGroupBeans.listIterator();
|
||||
int index = 0;
|
||||
while (iterator.hasNext()) {
|
||||
ConversationGroupBean next = iterator.next();
|
||||
if (next.getTitle().equals(oldName)) {
|
||||
next.setTitle(newName);
|
||||
adapter.notifyItemChanged(index);
|
||||
break;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyGroupUnreadMessageCountChanged(String groupName, long totalUnreadCount) {
|
||||
TUIConversationLog.d(TAG, "notifyGroupUnreadMessageCountChanged groupName =" + groupName + "count =" + totalUnreadCount);
|
||||
ListIterator<ConversationGroupBean> iterator = mConversationGroupBeans.listIterator();
|
||||
int index = 0;
|
||||
while (iterator.hasNext()) {
|
||||
ConversationGroupBean next = iterator.next();
|
||||
if (next.getTitle().equals(groupName)) {
|
||||
next.setUnReadCount(totalUnreadCount);
|
||||
refreshTabUnreadCount(index, totalUnreadCount);
|
||||
break;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
TUIConversationService.getInstance().setConversationGroupNotifyListener(conversationGroupNotifyListener);
|
||||
}
|
||||
|
||||
private void refreshTabUnreadCount(int position, long unreadCount) {
|
||||
TabLayout.Tab tab = mConversationTabLayout.getTabAt(position);
|
||||
if (tab != null) {
|
||||
View layoutView = tab.getCustomView();
|
||||
if (layoutView != null) {
|
||||
TextView unreadView = layoutView.findViewById(R.id.tab_unread);
|
||||
if (unreadCount == 0) {
|
||||
unreadView.setText("");
|
||||
} else if (unreadCount > 99) {
|
||||
unreadView.setText("99+");
|
||||
} else {
|
||||
unreadView.setText(String.valueOf(unreadCount));
|
||||
}
|
||||
}
|
||||
|
||||
int selectPositon = mConversationTabLayout.getSelectedTabPosition();
|
||||
if (selectPositon >= 0) {
|
||||
TabLayout.Tab selectedTab = mConversationTabLayout.getTabAt(selectPositon);
|
||||
if (selectedTab != null) {
|
||||
selectedTab.select();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addRefreshData(List<ConversationGroupBean> beans, boolean isMark) {
|
||||
List<ConversationGroupBean> markBeans = new ArrayList<>();
|
||||
List<ConversationGroupBean> groupBeans = new ArrayList<>();
|
||||
for (ConversationGroupBean bean : mConversationGroupBeans) {
|
||||
if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_MARK) {
|
||||
markBeans.add(bean);
|
||||
} else if (bean.getGroupType() == ConversationGroupBean.CONVERSATION_GROUP_TYPE_GROUP) {
|
||||
groupBeans.add(bean);
|
||||
}
|
||||
}
|
||||
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
if (isMark) {
|
||||
mConversationGroupBeans.removeAll(markBeans);
|
||||
} else {
|
||||
mConversationGroupBeans.removeAll(groupBeans);
|
||||
}
|
||||
} else {
|
||||
mConversationGroupBeans.clear();
|
||||
if (isMark) {
|
||||
mConversationGroupBeans.addAll(groupBeans);
|
||||
mConversationGroupBeans.addAll(beans);
|
||||
} else {
|
||||
mConversationGroupBeans.addAll(beans);
|
||||
mConversationGroupBeans.addAll(markBeans);
|
||||
}
|
||||
}
|
||||
|
||||
if (mConversationGroupBeans.isEmpty()) {
|
||||
refreshGroupView(true);
|
||||
} else {
|
||||
refreshGroupView(false);
|
||||
}
|
||||
|
||||
ConversationGroupBean bean = new ConversationGroupBean();
|
||||
bean.setTitle(getString(R.string.conversation_page_all));
|
||||
bean.setWeight(ConversationGroupBean.CONVERSATION_ALL_GROUP_WEIGHT);
|
||||
bean.setGroupType(ConversationGroupBean.CONVERSATION_GROUP_TYPE_DEFAULT);
|
||||
if (!mConversationGroupBeans.contains(bean)) {
|
||||
mConversationGroupBeans.add(bean);
|
||||
}
|
||||
|
||||
refreshConversationGroupSort();
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private ViewPager2.OnPageChangeCallback changeCallback = new ViewPager2.OnPageChangeCallback() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
TUIConversationLog.d(TAG, "onPageSelected position" + position);
|
||||
|
||||
selectedPosition = position;
|
||||
int tabCount = mConversationTabLayout.getTabCount();
|
||||
for (int i = 0; i < tabCount; i++) {
|
||||
TabLayout.Tab tab = mConversationTabLayout.getTabAt(i);
|
||||
View layoutView = tab.getCustomView();
|
||||
TextView titileView = layoutView.findViewById(R.id.tab_title);
|
||||
if (tab.getPosition() == position) {
|
||||
titileView.setTextColor(selectedColor);
|
||||
} else {
|
||||
titileView.setTextColor(getResources().getColor(com.tencent.qcloud.tuikit.timcommon.R.color.black));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void initSearchView() {
|
||||
TUICore.raiseExtension(TUIConstants.TUIConversation.Extension.ConversationListHeader.CLASSIC_EXTENSION_ID, searchLayout, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
TUIConversationLog.d(TAG, "onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
TUIConversationLog.d(TAG, "onDestroy");
|
||||
mediator.detach();
|
||||
mViewPager.unregisterOnPageChangeCallback(changeCallback);
|
||||
mConversationGroupBeans.clear();
|
||||
TUIConversationService.getInstance().setConversationGroupNotifyListenerNull();
|
||||
conversationGroupNotifyListener = null;
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
|
||||
public class TUIFoldedConversationActivity extends BaseLightActivity {
|
||||
private TUIFoldedConversationFragment mTUIFoldedConversationFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.conversation_folded_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIFoldedConversationFragment = new TUIFoldedConversationFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIFoldedConversationFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIExtensionEventListener;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUIExtensionInfo;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.FoldedConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIFoldedConversationFragment extends Fragment {
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private FoldedConversationLayout mFoldedLayout;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private ListView mConversationPopList;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.conversation_folded_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mFoldedLayout = mBaseView.findViewById(R.id.folded_conversation_layout);
|
||||
mTitleBarLayout = mFoldedLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle(getResources().getString(R.string.folded_group_chat), ITitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
presenter = new ConversationFoldPresenter();
|
||||
presenter.initListener();
|
||||
|
||||
mFoldedLayout.setPresenter(presenter);
|
||||
mFoldedLayout.initDefault();
|
||||
|
||||
mFoldedLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
return;
|
||||
}
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setWeight(800);
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
mFoldedLayout.markConversationHidden((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
conversationPopActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
action.setWeight(700);
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void restoreConversationItemBackground() {
|
||||
if (mFoldedLayout.getConversationList().getAdapter() != null && mFoldedLayout.getConversationList().getAdapter().isClick()) {
|
||||
mFoldedLayout.getConversationList().getAdapter().setClick(false);
|
||||
mFoldedLayout.getConversationList().getAdapter().notifyItemChanged(mFoldedLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
action.setWeight(900);
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
mConversationPopActions.addAll(addMoreConversationAction(conversationInfo));
|
||||
Collections.sort(mConversationPopActions, new Comparator<PopMenuAction>() {
|
||||
@Override
|
||||
public int compare(PopMenuAction o1, PopMenuAction o2) {
|
||||
return o2.getWeight() - o1.getWeight();
|
||||
}
|
||||
});
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = -view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mFoldedLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (presenter != null) {
|
||||
presenter.destroy();
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<PopMenuAction> addMoreConversationAction(ConversationInfo conversationInfo) {
|
||||
List<PopMenuAction> settingsList = new ArrayList<>();
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONTEXT, getContext());
|
||||
param.put(TUIConstants.TUIConversation.KEY_CONVERSATION_INFO, conversationInfo);
|
||||
List<TUIExtensionInfo> extensionList = TUICore.getExtensionList(TUIConstants.TUIConversation.Extension.ConversationPopMenu.CLASSIC_EXTENSION_ID, param);
|
||||
for (TUIExtensionInfo extensionInfo : extensionList) {
|
||||
String text = extensionInfo.getText();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
TUIExtensionEventListener listener = extensionInfo.getExtensionListener();
|
||||
if (listener != null) {
|
||||
listener.onClicked(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
action.setWeight(extensionInfo.getWeight());
|
||||
action.setActionName(text);
|
||||
settingsList.add(action);
|
||||
}
|
||||
}
|
||||
|
||||
return settingsList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.activities.BaseLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
|
||||
public class TUIForwardSelectActivity extends BaseLightActivity {
|
||||
private static final String TAG = TUIForwardSelectActivity.class.getSimpleName();
|
||||
|
||||
private TUIForwardSelectFragment mTUIForwardSelectFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.conversation_forward_activity_layout);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
TUIConversationLog.i(TAG, "onNewIntent");
|
||||
super.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
TUIConversationLog.i(TAG, "onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIForwardSelectFragment = new TUIForwardSelectFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIForwardSelectFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.page;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ForwardConversationSelectorAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.widget.ForwardSelectLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TUIForwardSelectFragment extends Fragment {
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private ForwardSelectLayout mForwardLayout;
|
||||
|
||||
private RecyclerView mForwardSelectlistView;
|
||||
private ForwardConversationSelectorAdapter mAdapter;
|
||||
private List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mContactDataSource = new ArrayList<>();
|
||||
private List<ConversationInfo> mAllSelectedConversations = new ArrayList<>();
|
||||
private RelativeLayout mForwardSelectlistViewLayout;
|
||||
private TextView mSureView;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
private static final String TAG = TUIForwardSelectFragment.class.getSimpleName();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.conversation_forward_fragment, container, false);
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
mForwardLayout = view.findViewById(R.id.forward_conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
mForwardLayout.setPresenter(presenter);
|
||||
|
||||
mForwardLayout.initDefault();
|
||||
|
||||
customizeConversation();
|
||||
mForwardLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
if (viewType == ConversationInfo.TYPE_RECENT_LABEL) {
|
||||
return;
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT) {
|
||||
if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))) {
|
||||
selectContactsToForward();
|
||||
} else if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))) {
|
||||
createNewConversationToForward();
|
||||
} else {
|
||||
TUIConversationLog.d(TAG, "Titlebar exception");
|
||||
}
|
||||
} else {
|
||||
if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))) {
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
checkRepeat();
|
||||
refreshSelectConversations();
|
||||
} else if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))) {
|
||||
forwardMessages(conversationInfo);
|
||||
} else {
|
||||
forwardMessages(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {}
|
||||
});
|
||||
|
||||
mForwardSelectlistViewLayout = view.findViewById(R.id.forward_select_list_layout);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mForwardSelectlistView = view.findViewById(R.id.forward_select_list);
|
||||
mForwardSelectlistView.setLayoutManager(new CustomLinearLayoutManager(getContext(), CustomLinearLayoutManager.HORIZONTAL, false));
|
||||
mAdapter = new ForwardConversationSelectorAdapter(this.getContext());
|
||||
mForwardSelectlistView.setAdapter(mAdapter);
|
||||
|
||||
mAdapter.setOnItemClickListener(new ForwardConversationSelectorAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position) {
|
||||
boolean needFresh = false;
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
if (position < mDataSource.size()) {
|
||||
mDataSource.remove(position);
|
||||
mForwardLayout.getConversationList().getAdapter().setSelectConversations(mDataSource);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!needFresh) {
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0) {
|
||||
int dataSourcePosition = mDataSource == null ? 0 : mDataSource.size();
|
||||
if (position - dataSourcePosition < mContactDataSource.size()) {
|
||||
mContactDataSource.remove(position - dataSourcePosition);
|
||||
needFresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needFresh) {
|
||||
refreshSelectConversations();
|
||||
}
|
||||
}
|
||||
});
|
||||
mSureView = view.findViewById(R.id.btn_msg_ok);
|
||||
mSureView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> conversationMap = new HashMap<>();
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
for (int i = 0; i < mDataSource.size(); i++) {
|
||||
conversationMap.put(mDataSource.get(i).getId(), mDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0) {
|
||||
for (int i = 0; i < mContactDataSource.size(); i++) {
|
||||
conversationMap.put(mContactDataSource.get(i).getId(), mContactDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, conversationMap);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelectConversations();
|
||||
initTitleAction();
|
||||
}
|
||||
|
||||
private void createNewConversationToForward() {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, true);
|
||||
TUICore.startActivityForResult(TUIForwardSelectFragment.this, "ForwardSelectGroupActivity", param, new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (getActivity() != null) {
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, result.getData());
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void selectContactsToForward() {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
param.putBoolean(TUIConversationConstants.FORWARD_CREATE_NEW_CHAT, false);
|
||||
TUICore.startActivityForResult(TUIForwardSelectFragment.this, "ForwardSelectGroupActivity", param, new ActivityResultCallback<ActivityResult>() {
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getData() == null) {
|
||||
return;
|
||||
}
|
||||
HashMap<String, String> conversationMap =
|
||||
(HashMap<String, String>) result.getData().getSerializableExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY);
|
||||
if (conversationMap == null || conversationMap.isEmpty()) {
|
||||
mContactDataSource.clear();
|
||||
refreshSelectConversations();
|
||||
return;
|
||||
}
|
||||
|
||||
mContactDataSource.clear();
|
||||
for (Map.Entry<String, String> entry : conversationMap.entrySet()) {
|
||||
ConversationInfo conversationInfo = new ConversationInfo();
|
||||
List<Object> iconList = new ArrayList<>();
|
||||
iconList.add(entry.getValue());
|
||||
conversationInfo.setIconUrlList(iconList);
|
||||
conversationInfo.setId(entry.getKey());
|
||||
conversationInfo.setGroup(false);
|
||||
mContactDataSource.add(conversationInfo);
|
||||
}
|
||||
checkRepeat();
|
||||
|
||||
refreshSelectConversations();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshSelectConversations() {
|
||||
mAllSelectedConversations.clear();
|
||||
|
||||
mDataSource = mForwardLayout.getConversationList().getAdapter().getSelectedItem();
|
||||
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
mAllSelectedConversations.addAll(mDataSource);
|
||||
}
|
||||
if (mContactDataSource != null && mContactDataSource.size() != 0) {
|
||||
mAllSelectedConversations.addAll(mContactDataSource);
|
||||
}
|
||||
|
||||
mAdapter.setDataSource(mAllSelectedConversations);
|
||||
|
||||
if (mAllSelectedConversations == null || mAllSelectedConversations.size() == 0) {
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure));
|
||||
mSureView.setVisibility(View.GONE);
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
mForwardSelectlistViewLayout.setVisibility(View.VISIBLE);
|
||||
mSureView.setVisibility(View.VISIBLE);
|
||||
mSureView.setText(getString(com.tencent.qcloud.tuicore.R.string.sure) + "(" + mAllSelectedConversations.size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void forwardMessages(final ConversationInfo conversationInfo) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle("");
|
||||
builder.setMessage(getString(R.string.forward_alert_title));
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(getString(com.tencent.qcloud.tuicore.R.string.sure), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> chatInfo = new HashMap<>();
|
||||
chatInfo.put(conversationInfo.getId(), conversationInfo.isGroup());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, chatInfo);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(com.tencent.qcloud.tuicore.R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void customizeConversation() {
|
||||
mTitleBarLayout = mForwardLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle("", TitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.getLeftGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), ITitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
mTitleBarLayout.getLeftIcon().setVisibility(View.GONE);
|
||||
mTitleBarLayout.getRightIcon().setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void initTitleAction() {
|
||||
mForwardLayout.getTitleBar().setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_cancle))) {
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.VISIBLE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_close), TitleBarLayout.Position.LEFT);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_mutiselect), TitleBarLayout.Position.RIGHT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(false);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
|
||||
mForwardSelectlistViewLayout.setVisibility(View.GONE);
|
||||
mAdapter.setDataSource(null);
|
||||
mAllSelectedConversations.clear();
|
||||
} else if (mTitleBarLayout.getLeftTitle().getText().equals(getString(R.string.titlebar_close))) {
|
||||
getActivity().finish();
|
||||
} else {
|
||||
TUIConversationLog.d(TAG, "Titlebar exception");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mForwardLayout.getTitleBar().setOnRightClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mTitleBarLayout.getRightGroup().setVisibility(View.GONE);
|
||||
mTitleBarLayout.setTitle(getString(R.string.titlebar_cancle), TitleBarLayout.Position.LEFT);
|
||||
|
||||
ConversationListLayout listLayout = mForwardLayout.getConversationList();
|
||||
listLayout.getAdapter().setShowMultiSelectCheckBox(true);
|
||||
listLayout.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkRepeat() {
|
||||
Iterator<ConversationInfo> iterator = mContactDataSource.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConversationInfo conversationInfo = iterator.next();
|
||||
if (mDataSource != null && mDataSource.size() != 0) {
|
||||
for (int i = 0; i < mDataSource.size(); i++) {
|
||||
if (conversationInfo.getId().equals(mDataSource.get(i).getId())) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
public static void startChatActivity(ConversationInfo conversationInfo) {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConstants.TUIChat.CHAT_TYPE, conversationInfo.isGroup() ? V2TIMConversation.V2TIM_GROUP : V2TIMConversation.V2TIM_C2C);
|
||||
param.putString(TUIConstants.TUIChat.CHAT_ID, conversationInfo.getId());
|
||||
param.putString(TUIConstants.TUIChat.CHAT_NAME, conversationInfo.getTitle());
|
||||
if (conversationInfo.getDraft() != null) {
|
||||
param.putString(TUIConstants.TUIChat.DRAFT_TEXT, conversationInfo.getDraft().getDraftText());
|
||||
param.putLong(TUIConstants.TUIChat.DRAFT_TIME, conversationInfo.getDraft().getDraftTime());
|
||||
}
|
||||
param.putBoolean(TUIConstants.TUIChat.IS_TOP_CHAT, conversationInfo.isTop());
|
||||
param.putString(TUIConstants.TUIChat.FACE_URL, conversationInfo.getIconPath());
|
||||
if (conversationInfo.isGroup()) {
|
||||
param.putString(TUIConstants.TUIChat.GROUP_TYPE, conversationInfo.getGroupType());
|
||||
param.putSerializable(TUIConstants.TUIChat.AT_INFO_LIST, (Serializable) conversationInfo.getGroupAtInfoList());
|
||||
}
|
||||
if (conversationInfo.isGroup()) {
|
||||
TUICore.startActivity(TUIConstants.TUIChat.GROUP_CHAT_ACTIVITY_NAME, param);
|
||||
} else {
|
||||
TUICore.startActivity(TUIConstants.TUIChat.C2C_CHAT_ACTIVITY_NAME, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public abstract class ConversationBaseHolder extends RecyclerView.ViewHolder {
|
||||
protected View rootView;
|
||||
protected ConversationListAdapter mAdapter;
|
||||
|
||||
public ConversationBaseHolder(View itemView) {
|
||||
super(itemView);
|
||||
rootView = itemView;
|
||||
}
|
||||
|
||||
public void setAdapter(RecyclerView.Adapter adapter) {
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
|
||||
public abstract void layoutViews(ConversationInfo conversationInfo, int position);
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.tencent.qcloud.tuicore.TUIThemeManager;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.UnreadCountTextView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.face.FaceManager;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.classicui.TUIConversationConfigClassic;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ConversationCommonHolder extends ConversationBaseHolder {
|
||||
public ConversationIconView conversationIconView;
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected UnreadCountTextView unreadText;
|
||||
protected TextView atAllTv;
|
||||
protected TextView atMeTv;
|
||||
protected TextView draftTv;
|
||||
protected TextView riskTv;
|
||||
protected TextView foldGroupNameTv;
|
||||
protected TextView foldGroupNameDivider;
|
||||
protected ImageView disturbView;
|
||||
protected ImageView markBannerView;
|
||||
protected CheckBox multiSelectCheckBox;
|
||||
protected RelativeLayout messageStatusLayout;
|
||||
public ImageView messageSending;
|
||||
public ImageView messageFailed;
|
||||
private boolean isForwardMode = false;
|
||||
protected View userStatusView;
|
||||
private boolean showFoldedStyle = true;
|
||||
private ConversationInfo currentConversation;
|
||||
|
||||
public ConversationCommonHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
foldGroupNameTv = rootView.findViewById(R.id.fold_group_name);
|
||||
foldGroupNameDivider = rootView.findViewById(R.id.fold_group_name_divider);
|
||||
atAllTv = rootView.findViewById(R.id.conversation_at_all);
|
||||
atMeTv = rootView.findViewById(R.id.conversation_at_me);
|
||||
draftTv = rootView.findViewById(R.id.conversation_draft);
|
||||
riskTv = rootView.findViewById(R.id.conversation_risk);
|
||||
disturbView = rootView.findViewById(R.id.not_disturb);
|
||||
markBannerView = rootView.findViewById(R.id.mark_banner);
|
||||
multiSelectCheckBox = rootView.findViewById(R.id.select_checkbox);
|
||||
messageStatusLayout = rootView.findViewById(R.id.message_status_layout);
|
||||
messageFailed = itemView.findViewById(R.id.message_status_failed);
|
||||
messageSending = itemView.findViewById(R.id.message_status_sending);
|
||||
userStatusView = itemView.findViewById(R.id.user_status);
|
||||
}
|
||||
|
||||
public void setForwardMode(boolean forwardMode) {
|
||||
isForwardMode = forwardMode;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
currentConversation = conversation;
|
||||
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
titleText.setText(R.string.folded_group_chat);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
foldGroupNameTv.setVisibility(View.VISIBLE);
|
||||
foldGroupNameDivider.setVisibility(View.VISIBLE);
|
||||
foldGroupNameTv.setText(conversation.getTitle());
|
||||
} else {
|
||||
titleText.setText(conversation.getTitle());
|
||||
foldGroupNameTv.setVisibility(View.GONE);
|
||||
foldGroupNameDivider.setVisibility(View.GONE);
|
||||
}
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
setLastMessageAndStatus(conversation);
|
||||
|
||||
if (!mAdapter.hasItemUnreadDot()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
conversationIconView.setShowFoldedStyle(showFoldedStyle);
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
if (conversation.isShowDisturbIcon() && !isForwardMode) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
} else {
|
||||
disturbView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (conversation.isMarkStar() && !isForwardMode) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
markBannerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
markBannerView.setVisibility(View.VISIBLE);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
markBannerView.setVisibility(View.GONE);
|
||||
timelineText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (isForwardMode) {
|
||||
messageText.setVisibility(View.GONE);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.GONE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
atAllTv.setVisibility(View.GONE);
|
||||
atMeTv.setVisibility(View.GONE);
|
||||
draftTv.setVisibility(View.GONE);
|
||||
riskTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (!conversation.isGroup() && TUIConversationConfigClassic.isShowUserOnlineStatusIcon()) {
|
||||
userStatusView.setVisibility(View.VISIBLE);
|
||||
if (conversation.getStatusType() == ConversationInfo.USER_STATUS_ONLINE) {
|
||||
userStatusView.setBackgroundResource(
|
||||
TUIThemeManager.getAttrResId(rootView.getContext(), com.tencent.qcloud.tuikit.timcommon.R.attr.user_status_online));
|
||||
} else {
|
||||
userStatusView.setBackgroundResource(
|
||||
TUIThemeManager.getAttrResId(rootView.getContext(), com.tencent.qcloud.tuikit.timcommon.R.attr.user_status_offline));
|
||||
}
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
applyCustomConfig();
|
||||
}
|
||||
|
||||
private void applyCustomConfig() {
|
||||
if (currentConversation.isTop() && !isForwardMode) {
|
||||
Drawable pinnedCellBackground = TUIConversationConfigClassic.getPinnedCellBackground();
|
||||
if (pinnedCellBackground != null) {
|
||||
leftItemLayout.setBackground(pinnedCellBackground);
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
}
|
||||
} else {
|
||||
Drawable cellBackground = TUIConversationConfigClassic.getCellBackground();
|
||||
if (cellBackground != null) {
|
||||
leftItemLayout.setBackground(cellBackground);
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
}
|
||||
if (!TUIConversationConfigClassic.isShowCellUnreadCount()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
disturbView.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TUIConversationConfigClassic.isShowUserOnlineStatusIcon()) {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
if (TUIConversationConfigClassic.getCellTitleLabelFontSize() != TUIConversationConfigClassic.UNDEFINED) {
|
||||
titleText.setTextSize(TUIConversationConfigClassic.getCellTitleLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigClassic.getCellSubtitleLabelFontSize() != TUIConversationConfigClassic.UNDEFINED) {
|
||||
messageText.setTextSize(TUIConversationConfigClassic.getCellSubtitleLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigClassic.getCellTimeLabelFontSize() != TUIConversationConfigClassic.UNDEFINED) {
|
||||
timelineText.setTextSize(TUIConversationConfigClassic.getCellTimeLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigClassic.getAvatarCornerRadius() != TUIConversationConfigClassic.UNDEFINED) {
|
||||
conversationIconView.setRadius(TUIConversationConfigClassic.getAvatarCornerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
private void setLastMessageAndStatus(ConversationInfo conversation) {
|
||||
DraftInfo draftInfo = conversation.getDraft();
|
||||
String draftText = "";
|
||||
if (draftInfo != null) {
|
||||
Gson gson = new Gson();
|
||||
HashMap draftJsonMap;
|
||||
draftText = draftInfo.getDraftText();
|
||||
try {
|
||||
draftJsonMap = gson.fromJson(draftInfo.getDraftText(), HashMap.class);
|
||||
if (draftJsonMap != null) {
|
||||
draftText = (String) draftJsonMap.get("content");
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
TUIConversationLog.e("ConversationCommonHolder", " getDraftJsonMap error ");
|
||||
}
|
||||
}
|
||||
|
||||
atAllTv.setVisibility(View.GONE);
|
||||
atMeTv.setVisibility(View.GONE);
|
||||
draftTv.setVisibility(View.GONE);
|
||||
riskTv.setVisibility(View.GONE);
|
||||
if (draftInfo != null) {
|
||||
messageText.setText(FaceManager.emojiJudge(draftText));
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(draftInfo.getDraftTime() * 1000)));
|
||||
} else {
|
||||
if (TUIConversationUtils.hasRiskContent(conversation.getLastMessage())) {
|
||||
riskTv.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
TUIMessageBean lasTUIMessageBean = conversation.getLastTUIMessageBean();
|
||||
if (lasTUIMessageBean != null) {
|
||||
String displayString = ConversationPresenter.getMessageDisplayString(lasTUIMessageBean);
|
||||
messageText.setText(displayString);
|
||||
messageText.setTextColor(rootView.getResources().getColor(R.color.list_bottom_text_bg));
|
||||
}
|
||||
if (conversation.getLastMessage() != null) {
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(conversation.getLastMessageTime() * 1000)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conversation.isShowDisturbIcon()) {
|
||||
if ((showFoldedStyle && conversation.isMarkFold())) {
|
||||
if (conversation.isMarkLocalUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (conversation.getUnRead() == 0) {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("");
|
||||
|
||||
if (messageText.getText() != null) {
|
||||
String text = messageText.getText().toString();
|
||||
messageText.setText("[" + conversation.getUnRead() + " " + rootView.getContext().getString(R.string.message_num) + "] " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("1");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ME) {
|
||||
atMeTv.setVisibility(View.VISIBLE);
|
||||
} else if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ALL) {
|
||||
atAllTv.setVisibility(View.VISIBLE);
|
||||
} else if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ALL_AND_ME) {
|
||||
atAllTv.setVisibility(View.VISIBLE);
|
||||
atMeTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (draftInfo != null) {
|
||||
draftTv.setVisibility(View.VISIBLE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (TUIConversationUtils.hasRiskContent(conversation.getLastMessage())) {
|
||||
messageFailed.setVisibility(View.VISIBLE);
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else {
|
||||
int status = conversation.getLastMessageStatus();
|
||||
if (status == ConversationInfo.LAST_MSG_STATUS_SEND_FAIL) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.VISIBLE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else if (status == ConversationInfo.LAST_MSG_STATUS_SENDING) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public class ConversationCustomHolder extends ConversationBaseHolder {
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected TextView unreadText;
|
||||
protected ConversationIconView conversationIconView;
|
||||
|
||||
public ConversationCustomHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
if (conversation.isTop()) {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
titleText.setText(conversation.getTitle());
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
|
||||
if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.gatherimage.SynthesizedImageView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ImageUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.TUIUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ThreadUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationIconPresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationIconView extends RelativeLayout {
|
||||
private static final int icon_size = ScreenUtil.getPxByDp(50);
|
||||
private ImageView mIconView;
|
||||
private boolean showFoldedStyle = false;
|
||||
|
||||
private ConversationIconPresenter presenter;
|
||||
|
||||
public ConversationIconView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), com.tencent.qcloud.tuikit.timcommon.R.layout.common_profile_icon_view, this);
|
||||
mIconView = findViewById(com.tencent.qcloud.tuikit.timcommon.R.id.profile_icon);
|
||||
((SynthesizedImageView) mIconView).defaultImage(TUIConfig.getDefaultAvatarImage());
|
||||
presenter = new ConversationIconPresenter();
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void setIconUrls(final List<Object> iconUrls, final String conversationId) {
|
||||
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).displayImage(iconUrls).load(conversationId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversation(ConversationInfo conversationInfo) {
|
||||
if (showFoldedStyle && conversationInfo.isMarkFold()) {
|
||||
mIconView.setImageResource(R.drawable.conversation_ic_fold);
|
||||
} else if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setImageId(conversationInfo.getConversationId());
|
||||
if (conversationInfo.isGroup()) {
|
||||
fillConversationUrlForGroup(conversationInfo);
|
||||
} else {
|
||||
setIconUrls(conversationInfo.getIconUrlList(), conversationInfo.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillConversationUrlForGroup(final ConversationInfo info) {
|
||||
List<Object> iconUrlList = info.getIconUrlList();
|
||||
if (iconUrlList == null || iconUrlList.size() == 0) {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar()) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadUtils.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String savedIcon = ImageUtil.getGroupConversationAvatar(info.getConversationId());
|
||||
if (TextUtils.isEmpty(savedIcon)) {
|
||||
fillFaceUrlList(info.getId(), info);
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(savedIcon);
|
||||
info.setIconUrlList(list);
|
||||
setIconUrls(list, info.getConversationId());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar() && iconUrlList.size() > 1) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
} else {
|
||||
setIconUrls(iconUrlList, info.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFaceUrlList(final String groupID, final ConversationInfo info) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearImage();
|
||||
presenter.getGroupMemberIconList(groupID, new IUIKitCallback<List<Object>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Object> data) {
|
||||
info.setIconUrlList(data);
|
||||
setIconUrls(data, info.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).defaultImage(TUIUtil.getDefaultGroupIconResIDByGroupType(getContext(), info.getGroupType()));
|
||||
}
|
||||
|
||||
setIconUrls(null, info.getConversationId());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setRadius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
mIconView.setImageBitmap(bd.getBitmap());
|
||||
}
|
||||
|
||||
public void setBitmapResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
Bitmap bitmap = ImageUtil.toRoundBitmap(bd.getBitmap());
|
||||
mIconView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
public void clearImage() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) mIconView).clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.classicui.TUIConversationConfigClassic;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private ConversationListLayout mConversationList;
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
public ConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (mConversationList != null) {
|
||||
mConversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.conversation_layout, this);
|
||||
mConversationList = findViewById(R.id.conversation_list);
|
||||
applyCustomConfig();
|
||||
}
|
||||
|
||||
private void applyCustomConfig() {
|
||||
Drawable listBackground = TUIConversationConfigClassic.getListBackground();
|
||||
if (listBackground != null) {
|
||||
mConversationList.setBackground(listBackground);
|
||||
}
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
if (presenter != null) {
|
||||
adapter.setShowFoldedStyle(true);
|
||||
}
|
||||
mConversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
mConversationList.loadConversation();
|
||||
mConversationList.loadMarkedConversation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return mConversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
if (presenter != null) {
|
||||
presenter.setConversationTop(conversation, callBack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.clearConversationMessage(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnreadAndCleanUnreadCount(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
if (presenter != null) {
|
||||
presenter.hideFoldItem(needHide);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
if (presenter != null) {
|
||||
presenter.setUnreadStatusOfFoldItem(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationListAdapter extends RecyclerView.Adapter implements IConversationListAdapter {
|
||||
public static final int ITEM_TYPE_HEADER_SEARCH = 101;
|
||||
public static final int ITEM_TYPE_FOOTER_LOADING = -99;
|
||||
public static final int ITEM_TYPE_NULL_DATA = 102;
|
||||
public static final int HEADER_COUNT = 1;
|
||||
public static final int FOOTER_COUNT = 1;
|
||||
public static final int SELECT_COUNT = 1;
|
||||
public static final int SELECT_LABEL_COUNT = 1;
|
||||
|
||||
private boolean mHasShowUnreadDot = true;
|
||||
protected List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private OnConversationAdapterListener mOnConversationAdapterListener;
|
||||
|
||||
private final HashMap<String, Boolean> mSelectedPositions = new HashMap<>();
|
||||
private boolean isShowMultiSelectCheckBox = false;
|
||||
private boolean isForwardFragment = false;
|
||||
private boolean isOnlyConversationSelect = false;
|
||||
protected List<String> mCannotSelectIds = new ArrayList<>();
|
||||
|
||||
private boolean mIsLoading = false;
|
||||
|
||||
private boolean isClick = false;
|
||||
private int currentPosition = -1;
|
||||
|
||||
private View searchView;
|
||||
|
||||
private boolean showFoldedStyle = true;
|
||||
|
||||
private String conversationGroupName = ConversationUtils.getConversationAllGroupName();
|
||||
|
||||
public ConversationListAdapter() {
|
||||
mCannotSelectIds.clear();
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public boolean isClick() {
|
||||
return isClick;
|
||||
}
|
||||
|
||||
public void setClick(boolean click) {
|
||||
isClick = click;
|
||||
}
|
||||
|
||||
public void setCannotSelectIds(List<String> list) {
|
||||
this.mCannotSelectIds = list;
|
||||
}
|
||||
|
||||
private boolean isInCannotSelectIds(String id) {
|
||||
if (mCannotSelectIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (mCannotSelectIds.contains(id)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentPosition(int currentPosition, boolean isClick) {
|
||||
this.currentPosition = currentPosition;
|
||||
this.isClick = isClick;
|
||||
}
|
||||
|
||||
public void setShowMultiSelectCheckBox(boolean show) {
|
||||
isShowMultiSelectCheckBox = show;
|
||||
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
mSelectedPositions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForwardFragment(boolean forwardFragment) {
|
||||
isForwardFragment = forwardFragment;
|
||||
}
|
||||
|
||||
public void setIsOnlyConversationSelect(boolean is) {
|
||||
this.isOnlyConversationSelect = is;
|
||||
}
|
||||
|
||||
public void setSearchView(View searchView) {
|
||||
this.searchView = searchView;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void setItemChecked(String conversationId, boolean isChecked) {
|
||||
mSelectedPositions.put(conversationId, isChecked);
|
||||
}
|
||||
|
||||
private boolean isItemChecked(String id) {
|
||||
if (mSelectedPositions.size() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSelectedPositions.containsKey(id)) {
|
||||
return mSelectedPositions.get(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConversationInfo> getSelectedItem() {
|
||||
if (mSelectedPositions.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
List<ConversationInfo> selectList = new ArrayList<>();
|
||||
for (int i = 0; i < getItemCount() - 1; i++) {
|
||||
ConversationInfo conversationInfo = getItem(i);
|
||||
if (conversationInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if (isItemChecked(conversationInfo.getConversationId())) {
|
||||
selectList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
return selectList;
|
||||
}
|
||||
|
||||
public void setSelectConversations(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null || dataSource.size() == 0) {
|
||||
mSelectedPositions.clear();
|
||||
notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
mSelectedPositions.clear();
|
||||
for (int i = 0; i < dataSource.size(); i++) {
|
||||
for (int j = 0; j < mDataSource.size(); j++) {
|
||||
if (TextUtils.equals(dataSource.get(i).getConversationId(), mDataSource.get(j).getConversationId())) {
|
||||
setItemChecked(mDataSource.get(j).getConversationId(), true);
|
||||
notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
this.mOnConversationAdapterListener = listener;
|
||||
}
|
||||
|
||||
public void setConversationGroupName(String groupName) {
|
||||
this.conversationGroupName = groupName;
|
||||
}
|
||||
|
||||
private boolean isShowNullConversationText() {
|
||||
if (mDataSource.isEmpty() && showFoldedStyle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataSourceChanged(List<ConversationInfo> dataSource) {
|
||||
this.mDataSource = dataSource;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
ConversationBaseHolder holder = null;
|
||||
|
||||
View view;
|
||||
|
||||
if (viewType == ITEM_TYPE_HEADER_SEARCH) {
|
||||
|
||||
if (searchView == null) {
|
||||
searchView = new View(parent.getContext());
|
||||
}
|
||||
return new HeaderViewHolder(searchView);
|
||||
} else if (viewType == ConversationInfo.TYPE_CUSTOM) {
|
||||
view = inflater.inflate(R.layout.conversation_custom_adapter, parent, false);
|
||||
holder = new ConversationCustomHolder(view);
|
||||
} else if (viewType == ITEM_TYPE_FOOTER_LOADING) {
|
||||
view = inflater.inflate(R.layout.conversation_loading_progress_bar, parent, false);
|
||||
return new FooterViewHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_FORWAR_SELECT) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_select_adapter, parent, false);
|
||||
return new ForwardSelectHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_RECENT_LABEL) {
|
||||
view = inflater.inflate(R.layout.conversation_forward_label_adapter, parent, false);
|
||||
return new ForwardLabelHolder(view);
|
||||
} else if (viewType == ITEM_TYPE_NULL_DATA) {
|
||||
view = inflater.inflate(R.layout.conversation_null_layout, parent, false);
|
||||
return new RecyclerView.ViewHolder(view) {};
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.conversation_list_item_layout, parent, false);
|
||||
holder = new ConversationCommonHolder(view);
|
||||
((ConversationCommonHolder) holder).setForwardMode(isForwardFragment);
|
||||
((ConversationCommonHolder) holder).setShowFoldedStyle(showFoldedStyle);
|
||||
}
|
||||
holder.setAdapter(this);
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
final ConversationInfo conversationInfo = getItem(position);
|
||||
ConversationBaseHolder baseHolder = null;
|
||||
if (conversationInfo != null) {
|
||||
baseHolder = (ConversationBaseHolder) holder;
|
||||
}
|
||||
|
||||
switch (getItemViewType(position)) {
|
||||
case ConversationInfo.TYPE_CUSTOM:
|
||||
case ConversationInfo.TYPE_RECENT_LABEL:
|
||||
break;
|
||||
case ITEM_TYPE_NULL_DATA:
|
||||
TextView nullTextView = holder.itemView.findViewById(R.id.conversation_null_text);
|
||||
nullTextView.setText(holder.itemView.getResources().getString(R.string.conversation_null_text, conversationGroupName));
|
||||
return;
|
||||
case ITEM_TYPE_FOOTER_LOADING: {
|
||||
if (holder instanceof FooterViewHolder) {
|
||||
((ConversationBaseHolder) holder).layoutViews(null, position);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConversationInfo.TYPE_FORWAR_SELECT: {
|
||||
ForwardSelectHolder selectHolder = (ForwardSelectHolder) holder;
|
||||
selectHolder.refreshTitle(!isShowMultiSelectCheckBox);
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
|
||||
if (baseHolder != null) {
|
||||
if (getCurrentPosition() == position && isClick()) {
|
||||
baseHolder.itemView.setBackgroundResource(R.color.conversation_item_clicked_color);
|
||||
}
|
||||
baseHolder.layoutViews(conversationInfo, position);
|
||||
setCheckBoxStatus(conversationInfo, position, baseHolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void setOnClickListener(RecyclerView.ViewHolder holder, int viewType, ConversationInfo conversationInfo) {
|
||||
if (holder instanceof HeaderViewHolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mOnConversationAdapterListener.onItemClick(view, viewType, conversationInfo);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
mOnConversationAdapterListener.onItemLongClick(view, conversationInfo);
|
||||
int position = getIndexInAdapter(conversationInfo);
|
||||
if (position != -1) {
|
||||
setCurrentPosition(position, true);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setCheckBoxStatus(final ConversationInfo conversationInfo, int position, ConversationBaseHolder baseHolder) {
|
||||
if (!(baseHolder instanceof ConversationCommonHolder) || ((ConversationCommonHolder) baseHolder).multiSelectCheckBox == null) {
|
||||
return;
|
||||
}
|
||||
int viewType = getItemViewType(position);
|
||||
String conversationId = conversationInfo.getConversationId();
|
||||
ConversationCommonHolder commonHolder = (ConversationCommonHolder) baseHolder;
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.GONE);
|
||||
} else {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.VISIBLE);
|
||||
|
||||
if (isInCannotSelectIds(conversationId)) {
|
||||
commonHolder.itemView.setEnabled(false);
|
||||
commonHolder.multiSelectCheckBox.setEnabled(false);
|
||||
commonHolder.itemView.setAlpha(0.5f);
|
||||
commonHolder.multiSelectCheckBox.setChecked(true);
|
||||
} else {
|
||||
commonHolder.itemView.setEnabled(true);
|
||||
commonHolder.multiSelectCheckBox.setEnabled(true);
|
||||
commonHolder.itemView.setAlpha(1f);
|
||||
|
||||
commonHolder.multiSelectCheckBox.setChecked(isItemChecked(conversationId));
|
||||
}
|
||||
|
||||
commonHolder.multiSelectCheckBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
baseHolder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
int currentPosition = getIndexInAdapter(conversationInfo);
|
||||
if (currentPosition != -1) {
|
||||
notifyItemChanged(currentPosition);
|
||||
}
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndexInAdapter(ConversationInfo conversationInfo) {
|
||||
int position = -1;
|
||||
if (mDataSource != null) {
|
||||
int indexInData = mDataSource.indexOf(conversationInfo);
|
||||
if (indexInData != -1) {
|
||||
position = getItemIndexInAdapter(indexInData);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
|
||||
|
||||
if (holder instanceof ConversationCommonHolder) {
|
||||
((ConversationCommonHolder) holder).conversationIconView.clearImage();
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationInfo getItem(int position) {
|
||||
if (mDataSource.isEmpty() || position == getItemCount() - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int dataPosition;
|
||||
if (isForwardFragment) {
|
||||
if (isOnlyConversationSelect) {
|
||||
dataPosition = position - SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
dataPosition = position - SELECT_COUNT - SELECT_LABEL_COUNT;
|
||||
}
|
||||
} else {
|
||||
dataPosition = position - HEADER_COUNT;
|
||||
}
|
||||
if (dataPosition < mDataSource.size() && dataPosition >= 0) {
|
||||
return mDataSource.get(dataPosition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int listSize = mDataSource.size();
|
||||
if (isForwardFragment) {
|
||||
if (isOnlyConversationSelect) {
|
||||
return listSize + SELECT_LABEL_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
return listSize + SELECT_COUNT + SELECT_LABEL_COUNT + FOOTER_COUNT;
|
||||
} else if (isShowNullConversationText()) {
|
||||
return 1;
|
||||
}
|
||||
return listSize + HEADER_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (isForwardFragment) {
|
||||
if (isOnlyConversationSelect) {
|
||||
if (position == 0) {
|
||||
return ConversationInfo.TYPE_RECENT_LABEL;
|
||||
}
|
||||
} else {
|
||||
if (position == 0) {
|
||||
return ConversationInfo.TYPE_FORWAR_SELECT;
|
||||
} else if (position == 1) {
|
||||
return ConversationInfo.TYPE_RECENT_LABEL;
|
||||
}
|
||||
}
|
||||
} else if (isShowNullConversationText()) {
|
||||
return ITEM_TYPE_NULL_DATA;
|
||||
} else {
|
||||
if (position == 0) {
|
||||
return ITEM_TYPE_HEADER_SEARCH;
|
||||
}
|
||||
}
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_TYPE_FOOTER_LOADING;
|
||||
} else if (mDataSource != null) {
|
||||
ConversationInfo conversationInfo = getItem(position);
|
||||
if (conversationInfo != null) {
|
||||
return conversationInfo.getType();
|
||||
}
|
||||
}
|
||||
return ConversationInfo.TYPE_COMMON;
|
||||
}
|
||||
|
||||
private int getItemIndexInAdapter(int index) {
|
||||
int itemIndex;
|
||||
if (isForwardFragment) {
|
||||
if (isOnlyConversationSelect) {
|
||||
itemIndex = index + SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
itemIndex = index + SELECT_LABEL_COUNT + SELECT_COUNT;
|
||||
}
|
||||
} else {
|
||||
itemIndex = index + HEADER_COUNT;
|
||||
}
|
||||
return itemIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRemoved(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemRemoved(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemInserted(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemInserted(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMoved(int fromPosition, int toPosition) {
|
||||
int fromIndex = getItemIndexInAdapter(fromPosition);
|
||||
int toIndex = getItemIndexInAdapter(toPosition);
|
||||
notifyItemMoved(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemChanged(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemChanged(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int startPosition, int count) {
|
||||
int itemStartIndex = getItemIndexInAdapter(startPosition);
|
||||
notifyItemRangeChanged(itemStartIndex, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mHasShowUnreadDot = !flag;
|
||||
}
|
||||
|
||||
public boolean hasItemUnreadDot() {
|
||||
return mHasShowUnreadDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChanged(boolean isLoading) {
|
||||
this.mIsLoading = isLoading;
|
||||
notifyItemChanged(getItemCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewNeedRefresh() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// header
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public HeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
// footer
|
||||
class FooterViewHolder extends ConversationBaseHolder {
|
||||
|
||||
public FooterViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) rootView.getLayoutParams();
|
||||
if (mIsLoading) {
|
||||
param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
|
||||
param.width = LinearLayout.LayoutParams.MATCH_PARENT;
|
||||
rootView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
param.height = 0;
|
||||
param.width = 0;
|
||||
rootView.setVisibility(View.GONE);
|
||||
}
|
||||
rootView.setLayoutParams(param);
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardLabelHolder extends ConversationBaseHolder {
|
||||
|
||||
public ForwardLabelHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {}
|
||||
}
|
||||
|
||||
static class ForwardSelectHolder extends ConversationBaseHolder {
|
||||
private final TextView titleView;
|
||||
|
||||
public ForwardSelectHolder(View itemView) {
|
||||
super(itemView);
|
||||
titleView = itemView.findViewById(R.id.forward_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {}
|
||||
|
||||
public void refreshTitle(boolean isCreateGroup) {
|
||||
if (titleView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCreateGroup) {
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_new_chat));
|
||||
} else {
|
||||
titleView.setText(TUIConversationService.getAppContext().getString(R.string.forward_select_from_contact));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
protected ConversationListAdapter mAdapter;
|
||||
protected ConversationPresenter presenter;
|
||||
|
||||
public ConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(int state) {
|
||||
super.onScrollStateChanged(state);
|
||||
if (state == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (layoutManager == null) {
|
||||
return;
|
||||
}
|
||||
int lastPosition = layoutManager.findLastCompletelyVisibleItemPosition();
|
||||
|
||||
if (mAdapter != null) {
|
||||
if (lastPosition == mAdapter.getItemCount() - 1 && !isLoadCompleted()) {
|
||||
mAdapter.onLoadingStateChanged(true);
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadMarkedConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadMarkedConversation();
|
||||
}
|
||||
}
|
||||
|
||||
public void reLoadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.reLoadConversation();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLoadCompleted() {
|
||||
if (presenter != null) {
|
||||
return presenter.isLoadFinished();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING;
|
||||
import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE;
|
||||
import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* A mediator to link a TabLayout with a ViewPager2. The mediator will synchronize the ViewPager2's
|
||||
* position with the selected tab when a tab is selected, and the TabLayout's scroll position when
|
||||
* the user drags the ViewPager2. ConversationTabLayoutMediator will listen to ViewPager2's OnPageChangeCallback
|
||||
* to adjust tab when ViewPager2 moves. ConversationTabLayoutMediator listens to TabLayout's
|
||||
* OnTabSelectedListener to adjust VP2 when tab moves. ConversationTabLayoutMediator listens to RecyclerView's
|
||||
* AdapterDataObserver to recreate tab content when dataset changes.
|
||||
*
|
||||
* <p>Establish the link by creating an instance of this class, make sure the ViewPager2 has an
|
||||
* adapter and then call {@link #attach()} on it. Instantiating a ConversationTabLayoutMediator will only create
|
||||
* the mediator object, {@link #attach()} will link the TabLayout and the ViewPager2 together. When
|
||||
* creating an instance of this class, you must supply an implementation of {@link
|
||||
* ConversationTabLayoutMediator.TabConfigurationStrategy} in which you set the text of the tab, and/or perform any styling of the
|
||||
* tabs that you require. Changing ViewPager2's adapter will require a {@link #detach()} followed by
|
||||
* {@link #attach()} call. Changing the ViewPager2 or TabLayout will require a new instantiation of
|
||||
* ConversationTabLayoutMediator.
|
||||
*/
|
||||
public class ConversationTabLayoutMediator {
|
||||
@NonNull private final TabLayout tabLayout;
|
||||
@NonNull private final ViewPager2 viewPager;
|
||||
private final boolean autoRefresh;
|
||||
private static boolean smoothScroll;
|
||||
private final ConversationTabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy;
|
||||
@Nullable private RecyclerView.Adapter<?> adapter;
|
||||
private boolean attached;
|
||||
|
||||
@Nullable private ConversationTabLayoutMediator.TabLayoutOnPageChangeCallback onPageChangeCallback;
|
||||
@Nullable private TabLayout.OnTabSelectedListener onTabSelectedListener;
|
||||
@Nullable private RecyclerView.AdapterDataObserver pagerAdapterObserver;
|
||||
|
||||
/**
|
||||
* A callback interface that must be implemented to set the text and styling of newly created
|
||||
* tabs.
|
||||
*/
|
||||
public interface TabConfigurationStrategy {
|
||||
/**
|
||||
* Called to configure the tab for the page at the specified position. Typically calls {@link
|
||||
* TabLayout.Tab#setText(CharSequence)}, but any form of styling can be applied.
|
||||
*
|
||||
* @param tab The Tab which should be configured to represent the title of the item at the given
|
||||
* position in the data set.
|
||||
* @param position The position of the item within the adapter's data set.
|
||||
*/
|
||||
void onConfigureTab(@NonNull TabLayout.Tab tab, int position);
|
||||
}
|
||||
|
||||
public ConversationTabLayoutMediator(
|
||||
@NonNull TabLayout tabLayout, @NonNull ViewPager2 viewPager, @NonNull ConversationTabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy) {
|
||||
this(tabLayout, viewPager, /* autoRefresh= */ true, tabConfigurationStrategy);
|
||||
}
|
||||
|
||||
public ConversationTabLayoutMediator(@NonNull TabLayout tabLayout, @NonNull ViewPager2 viewPager, boolean autoRefresh,
|
||||
@NonNull ConversationTabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy) {
|
||||
this(tabLayout, viewPager, autoRefresh, /* smoothScroll= */ true, tabConfigurationStrategy);
|
||||
}
|
||||
|
||||
public ConversationTabLayoutMediator(@NonNull TabLayout tabLayout, @NonNull ViewPager2 viewPager, boolean autoRefresh, boolean smoothScroll,
|
||||
@NonNull ConversationTabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy) {
|
||||
this.tabLayout = tabLayout;
|
||||
this.viewPager = viewPager;
|
||||
this.autoRefresh = autoRefresh;
|
||||
this.smoothScroll = smoothScroll;
|
||||
this.tabConfigurationStrategy = tabConfigurationStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link the TabLayout and the ViewPager2 together. Must be called after ViewPager2 has an adapter
|
||||
* set. To be called on a new instance of ConversationTabLayoutMediator or if the ViewPager2's adapter
|
||||
* changes.
|
||||
*
|
||||
* @throws IllegalStateException If the mediator is already attached, or the ViewPager2 has no
|
||||
* adapter.
|
||||
*/
|
||||
public void attach() {
|
||||
if (attached) {
|
||||
throw new IllegalStateException("ConversationTabLayoutMediator is already attached");
|
||||
}
|
||||
adapter = viewPager.getAdapter();
|
||||
if (adapter == null) {
|
||||
throw new IllegalStateException("ConversationTabLayoutMediator attached before ViewPager2 has an "
|
||||
+ "adapter");
|
||||
}
|
||||
attached = true;
|
||||
|
||||
// Add our custom OnPageChangeCallback to the ViewPager
|
||||
onPageChangeCallback = new ConversationTabLayoutMediator.TabLayoutOnPageChangeCallback(tabLayout);
|
||||
viewPager.registerOnPageChangeCallback(onPageChangeCallback);
|
||||
|
||||
// Now we'll add a tab selected listener to set ViewPager's current item
|
||||
onTabSelectedListener = new ConversationTabLayoutMediator.ViewPagerOnTabSelectedListener(viewPager, smoothScroll);
|
||||
tabLayout.addOnTabSelectedListener(onTabSelectedListener);
|
||||
|
||||
// Now we'll populate ourselves from the pager adapter, adding an observer if
|
||||
// autoRefresh is enabled
|
||||
if (autoRefresh) {
|
||||
// Register our observer on the new adapter
|
||||
pagerAdapterObserver = new ConversationTabLayoutMediator.PagerAdapterObserver();
|
||||
adapter.registerAdapterDataObserver(pagerAdapterObserver);
|
||||
}
|
||||
|
||||
populateTabsFromPagerAdapter();
|
||||
|
||||
// Now update the scroll position to match the ViewPager's current item
|
||||
tabLayout.setScrollPosition(viewPager.getCurrentItem(), 0f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink the TabLayout and the ViewPager. To be called on a stale ConversationTabLayoutMediator if a new one
|
||||
* is instantiated, to prevent holding on to a view that should be garbage collected. Also to be
|
||||
* called before {@link #attach()} when a ViewPager2's adapter is changed.
|
||||
*/
|
||||
public void detach() {
|
||||
if (autoRefresh && adapter != null) {
|
||||
adapter.unregisterAdapterDataObserver(pagerAdapterObserver);
|
||||
pagerAdapterObserver = null;
|
||||
}
|
||||
tabLayout.removeOnTabSelectedListener(onTabSelectedListener);
|
||||
viewPager.unregisterOnPageChangeCallback(onPageChangeCallback);
|
||||
onTabSelectedListener = null;
|
||||
onPageChangeCallback = null;
|
||||
adapter = null;
|
||||
attached = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link TabLayout} and the {@link ViewPager2} are linked together.
|
||||
*/
|
||||
public boolean isAttached() {
|
||||
return attached;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
void populateTabsFromPagerAdapter() {
|
||||
tabLayout.removeAllTabs();
|
||||
|
||||
if (adapter != null) {
|
||||
int adapterCount = adapter.getItemCount();
|
||||
for (int i = 0; i < adapterCount; i++) {
|
||||
TabLayout.Tab tab = tabLayout.newTab();
|
||||
tabConfigurationStrategy.onConfigureTab(tab, i);
|
||||
tabLayout.addTab(tab, false);
|
||||
}
|
||||
// Make sure we reflect the currently set ViewPager item
|
||||
if (adapterCount > 0) {
|
||||
int lastItem = tabLayout.getTabCount() - 1;
|
||||
int currItem = Math.min(viewPager.getCurrentItem(), lastItem);
|
||||
if (currItem != tabLayout.getSelectedTabPosition()) {
|
||||
tabLayout.selectTab(tabLayout.getTabAt(currItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ViewPager2.OnPageChangeCallback} class which contains the necessary calls back to the
|
||||
* provided {@link TabLayout} so that the tab position is kept in sync.
|
||||
*
|
||||
* <p>This class stores the provided TabLayout weakly, meaning that you can use {@link
|
||||
* ViewPager2#registerOnPageChangeCallback(ViewPager2.OnPageChangeCallback)} without removing the
|
||||
* callback and not cause a leak.
|
||||
*/
|
||||
private static class TabLayoutOnPageChangeCallback extends ViewPager2.OnPageChangeCallback {
|
||||
@NonNull private final WeakReference<TabLayout> tabLayoutRef;
|
||||
private int previousScrollState;
|
||||
private int scrollState;
|
||||
|
||||
TabLayoutOnPageChangeCallback(TabLayout tabLayout) {
|
||||
tabLayoutRef = new WeakReference<>(tabLayout);
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(final int state) {
|
||||
if (state == SCROLL_STATE_DRAGGING) {
|
||||
|
||||
smoothScroll = true;
|
||||
} else if (state == SCROLL_STATE_IDLE) {
|
||||
|
||||
smoothScroll = false;
|
||||
}
|
||||
previousScrollState = scrollState;
|
||||
scrollState = state;
|
||||
previousScrollState = scrollState;
|
||||
scrollState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
TabLayout tabLayout = tabLayoutRef.get();
|
||||
if (tabLayout != null) {
|
||||
// Only update the text selection if we're not settling, or we are settling after
|
||||
// being dragged
|
||||
boolean updateText = scrollState != SCROLL_STATE_SETTLING || previousScrollState == SCROLL_STATE_DRAGGING;
|
||||
// Update the indicator if we're not settling after being idle. This is caused
|
||||
// from a setCurrentItem() call and will be handled by an animation from
|
||||
// onPageSelected() instead.
|
||||
boolean updateIndicator = !(scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE);
|
||||
tabLayout.setScrollPosition(position, positionOffset, updateText, updateIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(final int position) {
|
||||
TabLayout tabLayout = tabLayoutRef.get();
|
||||
if (tabLayout != null && tabLayout.getSelectedTabPosition() != position && position < tabLayout.getTabCount()) {
|
||||
// Select the tab, only updating the indicator if we're not being dragged/settled
|
||||
// (since onPageScrolled will handle that).
|
||||
boolean updateIndicator =
|
||||
scrollState == SCROLL_STATE_IDLE || (scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE);
|
||||
tabLayout.selectTab(tabLayout.getTabAt(position), updateIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
previousScrollState = scrollState = SCROLL_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link TabLayout.OnTabSelectedListener} class which contains the necessary calls back to the
|
||||
* provided {@link ViewPager2} so that the tab position is kept in sync.
|
||||
*/
|
||||
private static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
|
||||
private final ViewPager2 viewPager;
|
||||
// private boolean smoothScroll;
|
||||
|
||||
ViewPagerOnTabSelectedListener(ViewPager2 viewPager, boolean smoothScroll) {
|
||||
this.viewPager = viewPager;
|
||||
// this.smoothScroll = smoothScroll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(@NonNull TabLayout.Tab tab) {
|
||||
viewPager.setCurrentItem(tab.getPosition(), smoothScroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
private class PagerAdapterObserver extends RecyclerView.AdapterDataObserver {
|
||||
PagerAdapterObserver() {}
|
||||
|
||||
@Override
|
||||
public void onChanged() {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount) {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||
populateTabsFromPagerAdapter();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private FoldedConversationListLayout conversationListLayout;
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
public FoldedConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationListLayout != null) {
|
||||
conversationListLayout.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.conversation_folded_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationListLayout = findViewById(R.id.folded_conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
conversationListLayout.setAdapter((IConversationListAdapter) adapter);
|
||||
adapter.setShowFoldedStyle(false);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
conversationListLayout.loadConversation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getConversationList() {
|
||||
return conversationListLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationFoldPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public FoldedConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import java.util.List;
|
||||
|
||||
public class ForwardConversationSelectorAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private Context context;
|
||||
private List<ConversationInfo> list;
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
|
||||
public ForwardConversationSelectorAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
super.onAttachedToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConversationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ConversationViewHolder(LayoutInflater.from(context).inflate(R.layout.conversation_forward_conversation_selector_item, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
ConversationViewHolder viewHolder = (ConversationViewHolder) holder;
|
||||
viewHolder.conversationUserIconView.setVisibility(View.VISIBLE);
|
||||
viewHolder.conversationUserIconView.setConversation(list.get(position));
|
||||
|
||||
viewHolder.conversationUserIconView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mOnItemClickListener.onClick(v, position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDataSource(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
if (list != null) {
|
||||
list.clear();
|
||||
}
|
||||
} else {
|
||||
list = dataSource;
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.mOnItemClickListener = listener;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(View view, int position);
|
||||
}
|
||||
|
||||
static class ConversationViewHolder extends RecyclerView.ViewHolder {
|
||||
public ConversationIconView conversationUserIconView;
|
||||
|
||||
public ConversationViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
conversationUserIconView = itemView.findViewById(R.id.conversation_user_icon_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.classicui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.classicui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ForwardSelectLayout extends RelativeLayout implements IConversationLayout {
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private ConversationListLayout conversationList;
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
public ForwardSelectLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationList != null) {
|
||||
conversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.conversation_forward_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationList = findViewById(R.id.conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
adapter.setForwardFragment(true);
|
||||
conversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
presenter.setAdapter(adapter);
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return conversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markRead) {}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupAtInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationUtils {
|
||||
private static final String TAG = ConversationUtils.class.getSimpleName();
|
||||
|
||||
public static List<ConversationInfo> convertV2TIMConversationList(List<V2TIMConversation> conversationList) {
|
||||
List<ConversationInfo> conversationInfoList = new ArrayList<>();
|
||||
if (conversationList != null) {
|
||||
for (V2TIMConversation conversation : conversationList) {
|
||||
conversationInfoList.add(convertV2TIMConversation(conversation));
|
||||
}
|
||||
}
|
||||
return conversationInfoList;
|
||||
}
|
||||
|
||||
public static ConversationInfo convertV2TIMConversation(final V2TIMConversation conversation) {
|
||||
if (conversation == null) {
|
||||
return null;
|
||||
}
|
||||
TUIConversationLog.i(TAG,
|
||||
"TIMConversation2ConversationInfo id:" + conversation.getConversationID() + "|name:" + conversation.getShowName()
|
||||
+ "|unreadNum:" + conversation.getUnreadCount());
|
||||
final ConversationInfo info = new ConversationInfo();
|
||||
info.setConversation(conversation);
|
||||
int type = conversation.getType();
|
||||
if (type != V2TIMConversation.V2TIM_C2C && type != V2TIMConversation.V2TIM_GROUP) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String draftText = conversation.getDraftText();
|
||||
if (!TextUtils.isEmpty(draftText)) {
|
||||
DraftInfo draftInfo = new DraftInfo();
|
||||
draftInfo.setDraftText(draftText);
|
||||
draftInfo.setDraftTime(conversation.getDraftTimestamp());
|
||||
info.setDraft(draftInfo);
|
||||
}
|
||||
V2TIMMessage message = conversation.getLastMessage();
|
||||
if (message == null) {
|
||||
long time = DateTimeUtil.getStringToDate("0001-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
|
||||
info.setLastMessageTime(time);
|
||||
} else {
|
||||
info.setLastMessageTime(message.getTimestamp());
|
||||
info.setLastMessage(message);
|
||||
}
|
||||
|
||||
int atInfoType = getAtInfoType(conversation);
|
||||
switch (atInfoType) {
|
||||
case V2TIMGroupAtInfo.TIM_AT_ME:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_me));
|
||||
info.setAtType(ConversationInfo.AT_TYPE_AT_ME);
|
||||
break;
|
||||
case V2TIMGroupAtInfo.TIM_AT_ALL:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_all));
|
||||
info.setAtType(ConversationInfo.AT_TYPE_AT_ALL);
|
||||
break;
|
||||
case V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME:
|
||||
info.setAtInfoText(TUIConversationService.getAppContext().getString(R.string.ui_at_all_me));
|
||||
info.setAtType(ConversationInfo.AT_TYPE_AT_ALL_AND_ME);
|
||||
break;
|
||||
default:
|
||||
info.setAtInfoText("");
|
||||
break;
|
||||
}
|
||||
|
||||
info.setTitle(conversation.getShowName());
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
boolean isGroup = type == V2TIMConversation.V2TIM_GROUP;
|
||||
if (isGroup) {
|
||||
if (!TextUtils.isEmpty(conversation.getFaceUrl())) {
|
||||
faceList.add(conversation.getFaceUrl());
|
||||
}
|
||||
} else {
|
||||
if (TextUtils.isEmpty(conversation.getFaceUrl())) {
|
||||
faceList.add(TUIConfig.getDefaultAvatarImage());
|
||||
} else {
|
||||
faceList.add(conversation.getFaceUrl());
|
||||
}
|
||||
}
|
||||
info.setIconPath(conversation.getFaceUrl());
|
||||
info.setIconUrlList(faceList);
|
||||
|
||||
if (isGroup) {
|
||||
info.setId(conversation.getGroupID());
|
||||
info.setGroupType(conversation.getGroupType());
|
||||
} else {
|
||||
info.setId(conversation.getUserID());
|
||||
}
|
||||
|
||||
if (V2TIMManager.GROUP_TYPE_MEETING.equals(conversation.getGroupType())) {
|
||||
info.setShowDisturbIcon(false);
|
||||
} else {
|
||||
info.setShowDisturbIcon(conversation.getRecvOpt() == V2TIMMessage.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE);
|
||||
}
|
||||
info.setConversationId(conversation.getConversationID());
|
||||
info.setGroup(isGroup);
|
||||
|
||||
if (!V2TIMManager.GROUP_TYPE_AVCHATROOM.equals(conversation.getGroupType())) {
|
||||
info.setUnRead(conversation.getUnreadCount());
|
||||
}
|
||||
info.setTop(conversation.isPinned());
|
||||
info.setOrderKey(conversation.getOrderKey());
|
||||
if (conversation.getMarkList() != null) {
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD)) {
|
||||
info.setMarkFold(true);
|
||||
} else {
|
||||
info.setMarkFold(false);
|
||||
}
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD)) {
|
||||
info.setMarkUnread(true);
|
||||
} else {
|
||||
info.setMarkUnread(false);
|
||||
}
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
|
||||
info.setMarkHidden(true);
|
||||
} else {
|
||||
info.setMarkHidden(false);
|
||||
}
|
||||
if (conversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR)) {
|
||||
info.setMarkStar(true);
|
||||
} else {
|
||||
info.setMarkStar(false);
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private static int getAtInfoType(V2TIMConversation conversation) {
|
||||
int atInfoType = 0;
|
||||
boolean atMe = false;
|
||||
boolean atAll = false;
|
||||
|
||||
List<V2TIMGroupAtInfo> atInfoList = conversation.getGroupAtInfoList();
|
||||
|
||||
if (atInfoList == null || atInfoList.isEmpty()) {
|
||||
return V2TIMGroupAtInfo.TIM_AT_UNKNOWN;
|
||||
}
|
||||
|
||||
for (V2TIMGroupAtInfo atInfo : atInfoList) {
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ME) {
|
||||
atMe = true;
|
||||
continue;
|
||||
}
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ALL) {
|
||||
atAll = true;
|
||||
continue;
|
||||
}
|
||||
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME) {
|
||||
atMe = true;
|
||||
atAll = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (atAll && atMe) {
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ALL_AT_ME;
|
||||
} else if (atAll) {
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ALL;
|
||||
} else if (atMe) {
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_ME;
|
||||
} else {
|
||||
atInfoType = V2TIMGroupAtInfo.TIM_AT_UNKNOWN;
|
||||
}
|
||||
|
||||
return atInfoType;
|
||||
}
|
||||
|
||||
public static boolean isIgnored(ConversationInfo conversationInfo) {
|
||||
if (V2TIMManager.GROUP_TYPE_AVCHATROOM.equals(conversationInfo.getGroupType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getListUnspecifiedWidth(PopDialogAdapter adapter, ListView listView) {
|
||||
if (adapter == null || listView == null) {
|
||||
return 0;
|
||||
}
|
||||
int maxWidth = 0;
|
||||
View convertView = null;
|
||||
int childCount = adapter.getCount();
|
||||
if (childCount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = adapter.getView(i, convertView, listView);
|
||||
child.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
maxWidth = Math.max(maxWidth, child.getMeasuredWidth() + child.getPaddingLeft() + child.getPaddingRight());
|
||||
convertView = child;
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
public static String getConversationAllGroupName() {
|
||||
return TUIConversationService.getAppContext().getResources().getString(R.string.conversation_page_all);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import com.tencent.imsdk.common.IMLog;
|
||||
|
||||
public class TUIConversationLog extends IMLog {
|
||||
private static final String PRE = "TUIConversation-";
|
||||
|
||||
private static String mixTag(String tag) {
|
||||
return PRE + tag;
|
||||
}
|
||||
|
||||
public static void v(String strTag, String strInfo) {
|
||||
IMLog.v(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void d(String strTag, String strInfo) {
|
||||
IMLog.d(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void i(String strTag, String strInfo) {
|
||||
IMLog.i(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void w(String strTag, String strInfo) {
|
||||
IMLog.w(mixTag(strTag), strInfo);
|
||||
}
|
||||
|
||||
public static void w(String strTag, String strInfo, Throwable e) {
|
||||
IMLog.w(mixTag(strTag), strInfo + e.getMessage());
|
||||
}
|
||||
|
||||
public static void e(String strTag, String strInfo) {
|
||||
IMLog.e(mixTag(strTag), strInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.commonutil;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
public static <T> void callbackOnError(IUIKitCallback<T> callBack, String module, int errCode, String desc) {
|
||||
if (callBack != null) {
|
||||
callBack.onError(module, errCode, ErrorMessageConverter.convertIMError(errCode, desc));
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void callbackOnError(IUIKitCallback<T> callBack, int errCode, String desc) {
|
||||
if (callBack != null) {
|
||||
callBack.onError(null, errCode, ErrorMessageConverter.convertIMError(errCode, desc));
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void callbackOnSuccess(IUIKitCallback<T> callBack, T data) {
|
||||
if (callBack != null) {
|
||||
callBack.onSuccess(data);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasRiskContent(V2TIMMessage v2TIMMessage) {
|
||||
if (v2TIMMessage != null) {
|
||||
return v2TIMMessage.hasRiskContent() && v2TIMMessage.getStatus() != V2TIMMessage.V2TIM_MSG_STATUS_LOCAL_REVOKED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.config;
|
||||
|
||||
public class TUIConversationConfig {
|
||||
public static final String TAG = TUIConversationConfig.class.getSimpleName();
|
||||
private static TUIConversationConfig instance;
|
||||
private boolean isShowUserStatus;
|
||||
|
||||
public static TUIConversationConfig getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new TUIConversationConfig();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean isShowUserStatus() {
|
||||
return isShowUserStatus;
|
||||
}
|
||||
|
||||
public void setShowUserStatus(boolean showUserStatus) {
|
||||
isShowUserStatus = showUserStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.config.classicui;
|
||||
|
||||
import static com.tencent.qcloud.tuikit.timcommon.util.TUIUtil.newDrawable;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationPopMenuItem;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIConversationConfigClassic {
|
||||
public static final int UNDEFINED = -1;
|
||||
|
||||
private TUIConversationConfigClassic() {}
|
||||
|
||||
private static final class TUIConversationConfigClassicHolder {
|
||||
private static final TUIConversationConfigClassic INSTANCE = new TUIConversationConfigClassic();
|
||||
}
|
||||
|
||||
private static TUIConversationConfigClassic getInstance() {
|
||||
return TUIConversationConfigClassicHolder.INSTANCE;
|
||||
}
|
||||
|
||||
public static final int HIDE = 1;
|
||||
public static final int DELETE = 2;
|
||||
|
||||
@IntDef({HIDE, DELETE})
|
||||
public @interface ConversationMenuItem {}
|
||||
|
||||
private Drawable listBackground;
|
||||
private Drawable cellBackground;
|
||||
private Drawable pinnedCellBackground;
|
||||
private int cellTitleLabelFontSize = UNDEFINED;
|
||||
private int cellSubtitleLabelFontSize = UNDEFINED;
|
||||
private int cellTimeLabelFontSize = UNDEFINED;
|
||||
private int avatarCornerRadius = UNDEFINED;
|
||||
private boolean showCellUnreadCount = true;
|
||||
private ConversationMenuItemDataSource conversationMenuItemDataSource;
|
||||
|
||||
/**
|
||||
* Set the background of the conversation list
|
||||
* @param listBackground
|
||||
*/
|
||||
public static void setListBackground(Drawable listBackground) {
|
||||
getInstance().listBackground = listBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the conversation list
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getListBackground() {
|
||||
return newDrawable(getInstance().listBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background of the conversation cell
|
||||
* @param cellBackground
|
||||
*/
|
||||
public static void setCellBackground(Drawable cellBackground) {
|
||||
getInstance().cellBackground = cellBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getCellBackground() {
|
||||
return newDrawable(getInstance().cellBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background of the pinned conversation cell
|
||||
* @param pinnedCellBackground
|
||||
*/
|
||||
public static void setPinnedCellBackground(Drawable pinnedCellBackground) {
|
||||
getInstance().pinnedCellBackground = pinnedCellBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the pinned conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getPinnedCellBackground() {
|
||||
return newDrawable(getInstance().pinnedCellBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell title label
|
||||
* @param cellTitleLabelFontSize
|
||||
*/
|
||||
public static void setCellTitleLabelFontSize(int cellTitleLabelFontSize) {
|
||||
getInstance().cellTitleLabelFontSize = cellTitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell title label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellTitleLabelFontSize() {
|
||||
return getInstance().cellTitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell subtitle label
|
||||
* @param cellSubtitleLabelFontSize
|
||||
*/
|
||||
public static void setCellSubtitleLabelFontSize(int cellSubtitleLabelFontSize) {
|
||||
getInstance().cellSubtitleLabelFontSize = cellSubtitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell subtitle label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellSubtitleLabelFontSize() {
|
||||
return getInstance().cellSubtitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell time label
|
||||
* @param cellTimeLabelFontSize
|
||||
*/
|
||||
public static void setCellTimeLabelFontSize(int cellTimeLabelFontSize) {
|
||||
getInstance().cellTimeLabelFontSize = cellTimeLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell time label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellTimeLabelFontSize() {
|
||||
return getInstance().cellTimeLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radius of the conversation cell avatar
|
||||
* @param avatarCornerRadius
|
||||
*/
|
||||
public static void setAvatarCornerRadius(int avatarCornerRadius) {
|
||||
getInstance().avatarCornerRadius = avatarCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the corner radius of the conversation cell avatar
|
||||
* @return
|
||||
*/
|
||||
public static int getAvatarCornerRadius() {
|
||||
return getInstance().avatarCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to show the user online status icon
|
||||
* @param showUserOnlineStatusIcon
|
||||
*/
|
||||
public static void setShowUserOnlineStatusIcon(boolean showUserOnlineStatusIcon) {
|
||||
TUIConversationConfig.getInstance().setShowUserStatus(showUserOnlineStatusIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to show the user online status icon on the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShowUserOnlineStatusIcon() {
|
||||
return TUIConversationConfig.getInstance().isShowUserStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to show the unread count of the conversation cell
|
||||
* @param showCellUnreadCount
|
||||
*/
|
||||
public static void setShowCellUnreadCount(boolean showCellUnreadCount) {
|
||||
getInstance().showCellUnreadCount = showCellUnreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to show the unread count of the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShowCellUnreadCount() {
|
||||
return getInstance().showCellUnreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data source of the conversation long-press menu item
|
||||
* @param conversationMenuItemDataSource
|
||||
* @see ConversationMenuItemDataSource
|
||||
*/
|
||||
public static void setConversationMenuItemDataSource(ConversationMenuItemDataSource conversationMenuItemDataSource) {
|
||||
getInstance().conversationMenuItemDataSource = conversationMenuItemDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data source of the conversation long-press menu item
|
||||
* @return the data source
|
||||
* @see ConversationMenuItemDataSource
|
||||
*/
|
||||
public static ConversationMenuItemDataSource getConversationMenuItemDataSource() {
|
||||
return getInstance().conversationMenuItemDataSource;
|
||||
}
|
||||
|
||||
public interface ConversationMenuItemDataSource {
|
||||
/**
|
||||
* Implement this method to add new items.
|
||||
* @param conversationInfo
|
||||
* @return the items to be added
|
||||
*/
|
||||
default List<PopMenuAction> conversationShouldAddNewItemsToMoreMenu(ConversationInfo conversationInfo) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to hide items in more menu.
|
||||
* @param conversationInfo
|
||||
* @return the items to be hidden
|
||||
*/
|
||||
default @ConversationMenuItem List<Integer> conversationShouldHideItemsInMoreMenu(ConversationInfo conversationInfo) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.config.minimalistui;
|
||||
|
||||
import static com.tencent.qcloud.tuikit.timcommon.util.TUIUtil.newDrawable;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import androidx.annotation.IntDef;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationPopMenuItem;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.classicui.TUIConversationConfigClassic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIConversationConfigMinimalist {
|
||||
public static final int UNDEFINED = -1;
|
||||
|
||||
private TUIConversationConfigMinimalist() {}
|
||||
|
||||
private static final class TUIConversationConfigMinimalistHolder {
|
||||
private static final TUIConversationConfigMinimalist INSTANCE = new TUIConversationConfigMinimalist();
|
||||
}
|
||||
|
||||
private static TUIConversationConfigMinimalist getInstance() {
|
||||
return TUIConversationConfigMinimalistHolder.INSTANCE;
|
||||
}
|
||||
|
||||
public static final int HIDE = 1;
|
||||
public static final int PIN = 2;
|
||||
public static final int CLEAR = 3;
|
||||
public static final int DELETE = 4;
|
||||
|
||||
@IntDef({HIDE, PIN, CLEAR, DELETE})
|
||||
public @interface ConversationMenuItem {}
|
||||
|
||||
private Drawable listBackground;
|
||||
private Drawable cellBackground;
|
||||
private Drawable pinnedCellBackground;
|
||||
private int cellTitleLabelFontSize = UNDEFINED;
|
||||
private int cellSubtitleLabelFontSize = UNDEFINED;
|
||||
private int cellTimeLabelFontSize = UNDEFINED;
|
||||
private int avatarCornerRadius = UNDEFINED;
|
||||
private boolean showCellUnreadCount = true;
|
||||
private ConversationMenuItemDataSource conversationMenuItemDataSource;
|
||||
|
||||
/**
|
||||
* Set the background of the conversation list
|
||||
* @param listBackground
|
||||
*/
|
||||
public static void setListBackground(Drawable listBackground) {
|
||||
getInstance().listBackground = listBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the conversation list
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getListBackground() {
|
||||
return newDrawable(getInstance().listBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background of the conversation cell
|
||||
* @param cellBackground
|
||||
*/
|
||||
public static void setCellBackground(Drawable cellBackground) {
|
||||
getInstance().cellBackground = cellBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getCellBackground() {
|
||||
return newDrawable(getInstance().cellBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background of the pinned conversation cell
|
||||
* @param pinnedCellBackground
|
||||
*/
|
||||
public static void setPinnedCellBackground(Drawable pinnedCellBackground) {
|
||||
getInstance().pinnedCellBackground = pinnedCellBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background of the pinned conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getPinnedCellBackground() {
|
||||
return newDrawable(getInstance().pinnedCellBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell title label
|
||||
* @param cellTitleLabelFontSize
|
||||
*/
|
||||
public static void setCellTitleLabelFontSize(int cellTitleLabelFontSize) {
|
||||
getInstance().cellTitleLabelFontSize = cellTitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell title label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellTitleLabelFontSize() {
|
||||
return getInstance().cellTitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell subtitle label
|
||||
* @param cellSubtitleLabelFontSize
|
||||
*/
|
||||
public static void setCellSubtitleLabelFontSize(int cellSubtitleLabelFontSize) {
|
||||
getInstance().cellSubtitleLabelFontSize = cellSubtitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell subtitle label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellSubtitleLabelFontSize() {
|
||||
return getInstance().cellSubtitleLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font size of the conversation cell time label
|
||||
* @param cellTimeLabelFontSize
|
||||
*/
|
||||
public static void setCellTimeLabelFontSize(int cellTimeLabelFontSize) {
|
||||
getInstance().cellTimeLabelFontSize = cellTimeLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font size of the conversation cell time label
|
||||
* @return
|
||||
*/
|
||||
public static int getCellTimeLabelFontSize() {
|
||||
return getInstance().cellTimeLabelFontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radius of the conversation cell avatar
|
||||
* @param avatarCornerRadius
|
||||
*/
|
||||
public static void setAvatarCornerRadius(int avatarCornerRadius) {
|
||||
getInstance().avatarCornerRadius = avatarCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the corner radius of the conversation cell avatar
|
||||
* @return
|
||||
*/
|
||||
public static int getAvatarCornerRadius() {
|
||||
return getInstance().avatarCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to show the user online status icon
|
||||
* @param showUserOnlineStatusIcon
|
||||
*/
|
||||
public static void setShowUserOnlineStatusIcon(boolean showUserOnlineStatusIcon) {
|
||||
TUIConversationConfig.getInstance().setShowUserStatus(showUserOnlineStatusIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to show the user online status icon on the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShowUserOnlineStatusIcon() {
|
||||
return TUIConversationConfig.getInstance().isShowUserStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to show the unread count of the conversation cell
|
||||
* @param showCellUnreadCount
|
||||
*/
|
||||
public static void setShowCellUnreadCount(boolean showCellUnreadCount) {
|
||||
getInstance().showCellUnreadCount = showCellUnreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to show the unread count of the conversation cell
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShowCellUnreadCount() {
|
||||
return getInstance().showCellUnreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data source of the conversation long-press menu item
|
||||
* @param conversationMenuItemDataSource
|
||||
* @see TUIConversationConfigClassic.ConversationMenuItemDataSource
|
||||
*/
|
||||
public static void setConversationMenuItemDataSource(ConversationMenuItemDataSource conversationMenuItemDataSource) {
|
||||
getInstance().conversationMenuItemDataSource = conversationMenuItemDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data source of the conversation long-press menu item
|
||||
* @return the data source
|
||||
* @see TUIConversationConfigClassic.ConversationMenuItemDataSource
|
||||
*/
|
||||
public static ConversationMenuItemDataSource getConversationMenuItemDataSource() {
|
||||
return getInstance().conversationMenuItemDataSource;
|
||||
}
|
||||
|
||||
public interface ConversationMenuItemDataSource {
|
||||
/**
|
||||
* Implement this method to add new items.
|
||||
* @param conversationInfo
|
||||
* @return the items to be added
|
||||
*/
|
||||
default List<ConversationPopMenuItem> conversationShouldAddNewItemsToMoreMenu(ConversationInfo conversationInfo) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to hide items in more menu.
|
||||
* @param conversationInfo
|
||||
* @return the items to be hidden
|
||||
*/
|
||||
default @ConversationMenuItem List<Integer> conversationShouldHideItemsInMoreMenu(ConversationInfo conversationInfo) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.interfaces;
|
||||
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ConversationEventListener {
|
||||
|
||||
void deleteConversation(String chatId, boolean isGroup);
|
||||
|
||||
void clearConversationMessage(String chatId, boolean isGroup);
|
||||
|
||||
void clearFoldMarkAndDeleteConversation(String conversationId);
|
||||
|
||||
void setConversationTop(String chatId, boolean isChecked, IUIKitCallback<Void> iuiKitCallBack);
|
||||
|
||||
boolean isTopConversation(String chatId);
|
||||
|
||||
long getUnreadTotal();
|
||||
|
||||
void onSyncServerFinish();
|
||||
|
||||
void updateTotalUnreadMessageCount(long count);
|
||||
|
||||
void onNewConversation(List<ConversationInfo> conversationList);
|
||||
|
||||
void onConversationChanged(List<ConversationInfo> conversationList);
|
||||
|
||||
void onFriendRemarkChanged(String id, String remark);
|
||||
|
||||
void onUserStatusChanged(List<V2TIMUserStatus> userStatusList);
|
||||
|
||||
void refreshUserStatusFragmentUI();
|
||||
|
||||
void onReceiveMessage(String conversationID, boolean isTypingMessage);
|
||||
|
||||
void onMessageSendForHideConversation(String conversationID);
|
||||
|
||||
void onConversationDeleted(List<String> conversationIDList);
|
||||
|
||||
void onConversationLastMessageBeanChanged(String conversationID, TUIMessageBean messageBean);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationGroupBean;
|
||||
import java.util.List;
|
||||
|
||||
public interface ConversationGroupNotifyListener {
|
||||
void notifyGroupsAdd(List<ConversationGroupBean> beans);
|
||||
|
||||
void notifyMarkGroupsAdd(List<ConversationGroupBean> beans);
|
||||
|
||||
void notifyGroupAdd(ConversationGroupBean bean);
|
||||
|
||||
void notifyGroupDelete(String groupName);
|
||||
|
||||
void notifyGroupRename(String oldName, String newName);
|
||||
|
||||
void notifyGroupUnreadMessageCountChanged(String groupName, long totalUnreadCount);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IConversationListAdapter {
|
||||
/**
|
||||
* Get the entry data of the adapter, which returns the ConversationInfo object or its sub-objects
|
||||
*
|
||||
* @param position
|
||||
* @return ConversationInfo
|
||||
*/
|
||||
ConversationInfo getItem(int position);
|
||||
|
||||
void onLoadingStateChanged(boolean isLoading);
|
||||
|
||||
void onDataSourceChanged(List<ConversationInfo> conversationInfoList);
|
||||
|
||||
void onViewNeedRefresh();
|
||||
|
||||
void onItemRemoved(int position);
|
||||
|
||||
default void onItemMoved(int fromPosition, int toPosition) {}
|
||||
|
||||
void onItemInserted(int position);
|
||||
|
||||
void onItemChanged(int position);
|
||||
|
||||
void onItemRangeChanged(int startPosition, int count);
|
||||
|
||||
void onConversationChanged(List<ConversationInfo> conversationInfoList);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.ILayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public interface IConversationLayout extends ILayout {
|
||||
View getConversationList();
|
||||
|
||||
void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack);
|
||||
|
||||
void deleteConversation(ConversationInfo conversation);
|
||||
|
||||
void clearConversationMessage(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* Hide normal conversation
|
||||
*/
|
||||
void markConversationHidden(ConversationInfo conversation);
|
||||
|
||||
/**
|
||||
* Mark conversation read or unread
|
||||
*/
|
||||
void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread);
|
||||
|
||||
/**
|
||||
* Hide folded conversation item
|
||||
*/
|
||||
void hideFoldedItem(boolean needHide);
|
||||
|
||||
/**
|
||||
* item
|
||||
* Clear unread status of fold item
|
||||
*/
|
||||
void clearUnreadStatusOfFoldItem();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListAdapter;
|
||||
|
||||
public interface IConversationListLayout {
|
||||
void setBackground(int resId);
|
||||
|
||||
void setOnConversationAdapterListener(OnConversationAdapterListener listener);
|
||||
|
||||
/**
|
||||
* Do not display the switch for the number of unread messages with the small red dot
|
||||
*/
|
||||
void disableItemUnreadDot(boolean flag);
|
||||
|
||||
View getListLayout();
|
||||
|
||||
ConversationListAdapter getAdapter();
|
||||
|
||||
void setAdapter(IConversationListAdapter adapter);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IConversationProvider {
|
||||
/**
|
||||
* Get a specific session data set, and ConversationContainer displays the session list based on the data set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ConversationInfo> getDataSource();
|
||||
|
||||
/**
|
||||
* Bulk add session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean addConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Delete session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean deleteConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Update session entries
|
||||
*
|
||||
* @param conversations
|
||||
* @return
|
||||
*/
|
||||
boolean updateConversations(List<ConversationInfo> conversations);
|
||||
|
||||
/**
|
||||
* Called when a session adapter is bound, automatically called when {@link
|
||||
* com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter#setDataProvider} is called
|
||||
*
|
||||
* @param adapter UI
|
||||
* @return
|
||||
*/
|
||||
|
||||
void attachAdapter(IConversationListAdapter adapter);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OnConversationAdapterListener {
|
||||
void onItemClick(View view, int viewType, ConversationInfo conversationInfo);
|
||||
|
||||
void onItemLongClick(View view, ConversationInfo conversationInfo);
|
||||
|
||||
void onConversationChanged(List<ConversationInfo> dataSource);
|
||||
|
||||
void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread);
|
||||
|
||||
void onMarkConversationHidden(View view, ConversationInfo conversationInfo);
|
||||
|
||||
void onClickMoreView(View view, ConversationInfo conversationInfo);
|
||||
|
||||
void onSwipeConversationChanged(ConversationInfo conversationInfo);
|
||||
}
|
||||
@@ -0,0 +1,567 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationPopMenuItem;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.minimalistui.TUIConversationConfigMinimalist;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.Menu;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIConversationMinimalistFragment extends Fragment {
|
||||
private View mBaseView;
|
||||
private ConversationLayout mConversationLayout;
|
||||
private AlertDialog mBottomDialog;
|
||||
private boolean isShowReadButton;
|
||||
private boolean isShowReadAllButton;
|
||||
private BroadcastReceiver unreadCountReceiver;
|
||||
private Menu menu;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
private ConversationListAdapter mAdapter;
|
||||
private String title;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalistui_conversation_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mConversationLayout.initUI();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mConversationLayout = mBaseView.findViewById(R.id.conversation_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
presenter.setConversationListener();
|
||||
presenter.setShowType(ConversationPresenter.SHOW_TYPE_CONVERSATION_LIST_WITH_FOLD);
|
||||
mConversationLayout.setPresenter(presenter);
|
||||
|
||||
mConversationLayout.initDefault();
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
mConversationLayout.setTitle(title);
|
||||
}
|
||||
|
||||
isShowReadButton = false;
|
||||
isShowReadAllButton = false;
|
||||
mAdapter = mConversationLayout.getConversationList().getAdapter();
|
||||
mConversationLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
if (mConversationLayout.isMultiSelected()) {
|
||||
if (mAdapter == null) {
|
||||
refreshEditConversationDialog(0);
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
if (mSelectConversations == null) {
|
||||
refreshEditConversationDialog(0);
|
||||
return;
|
||||
}
|
||||
isShowReadButton = false;
|
||||
for (ConversationInfo conversation : mSelectConversations) {
|
||||
if (conversation.isMarkUnread() || conversation.getUnRead() > 0) {
|
||||
isShowReadButton = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
refreshEditConversationDialog(mSelectConversations.size());
|
||||
} else if (conversationInfo.isMarkFold()) {
|
||||
mConversationLayout.clearUnreadStatusOfFoldItem();
|
||||
startFoldedConversationActivity();
|
||||
} else {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {
|
||||
showConversationMoreActionDialog(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {}
|
||||
});
|
||||
|
||||
mConversationLayout.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onEditConversationStartClick() {
|
||||
showEditConversationDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditConversationEndClick() {
|
||||
closeEditConversationDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartChatClick() {
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
if (menu.isShowing()) {
|
||||
menu.hide();
|
||||
} else {
|
||||
menu.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishActivity() {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
initUnreadCountReceiver();
|
||||
restoreConversationItemBackground();
|
||||
setConversationMenu();
|
||||
}
|
||||
|
||||
public void restoreConversationItemBackground() {
|
||||
if (mConversationLayout.getConversationList().getAdapter() != null && mConversationLayout.getConversationList().getAdapter().isClick()) {
|
||||
mConversationLayout.getConversationList().getAdapter().setClick(false);
|
||||
mConversationLayout.getConversationList().getAdapter().notifyItemChanged(
|
||||
mConversationLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public void setConversationTitle(String title) {
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
this.title = title;
|
||||
if (mConversationLayout != null) {
|
||||
mConversationLayout.setTitle(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initUnreadCountReceiver() {
|
||||
unreadCountReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
long unreadCount = intent.getLongExtra(TUIConstants.UNREAD_COUNT_EXTRA, 0);
|
||||
if (unreadCount > 0) {
|
||||
isShowReadAllButton = true;
|
||||
} else {
|
||||
isShowReadAllButton = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
IntentFilter unreadCountFilter = new IntentFilter();
|
||||
unreadCountFilter.addAction(TUIConstants.CONVERSATION_UNREAD_COUNT_ACTION);
|
||||
LocalBroadcastManager.getInstance(getContext()).registerReceiver(unreadCountReceiver, unreadCountFilter);
|
||||
}
|
||||
|
||||
private void startFoldedConversationActivity() {
|
||||
Intent intent = new Intent(getActivity(), TUIFoldedConversationMinimalistActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public interface OnClickListener {
|
||||
void onEditConversationStartClick();
|
||||
|
||||
void onEditConversationEndClick();
|
||||
|
||||
void onStartChatClick();
|
||||
|
||||
void finishActivity();
|
||||
}
|
||||
|
||||
private void showEditConversationDialog() {
|
||||
if (mBottomDialog != null && mBottomDialog.isShowing()) {
|
||||
return;
|
||||
}
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.minimalist_bottom_bar, null, false);
|
||||
mBottomDialog = new AlertDialog.Builder(getContext()).setView(view).create();
|
||||
|
||||
TextView markReadView = view.findViewById(R.id.mark_read);
|
||||
TextView notDisplayView = view.findViewById(R.id.not_display);
|
||||
|
||||
if (isShowReadAllButton) {
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
markReadView.setText(getString(R.string.has_all_read));
|
||||
} else {
|
||||
markReadView.setAlpha(0.5f);
|
||||
markReadView.setEnabled(false);
|
||||
markReadView.setText(getString(R.string.mark_read));
|
||||
}
|
||||
TextView deleteChatView = view.findViewById(R.id.delete_chat);
|
||||
notDisplayView.setAlpha(0.5f);
|
||||
notDisplayView.setEnabled(false);
|
||||
deleteChatView.setAlpha(0.5f);
|
||||
deleteChatView.setEnabled(false);
|
||||
|
||||
markReadView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (markReadView.getText().equals(getString(R.string.has_all_read))) {
|
||||
presenter.clearAllUnreadMessage();
|
||||
} else {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for (ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
notDisplayView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for (ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
deleteChatView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter == null) {
|
||||
resetEditConversationStatus();
|
||||
return;
|
||||
}
|
||||
List<ConversationInfo> mSelectConversations = mAdapter.getSelectedItem();
|
||||
for (ConversationInfo conversationInfo : mSelectConversations) {
|
||||
mConversationLayout.deleteConversation(conversationInfo);
|
||||
}
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
});
|
||||
|
||||
mBottomDialog.setCanceledOnTouchOutside(false);
|
||||
mBottomDialog.show();
|
||||
Window win = mBottomDialog.getWindow();
|
||||
win.setGravity(Gravity.BOTTOM);
|
||||
win.getDecorView().setPaddingRelative(0, 0, 0, 0);
|
||||
WindowManager.LayoutParams lp = win.getAttributes();
|
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mBottomDialog.getWindow().setBackgroundDrawableResource(R.color.conversation_bottom_bg);
|
||||
win.setAttributes(lp);
|
||||
|
||||
win.setDimAmount(0f);
|
||||
win.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
|
||||
win.setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
|
||||
|
||||
mBottomDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
resetEditConversationStatus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshEditConversationDialog(int selectSize) {
|
||||
if (mBottomDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TextView markReadView = mBottomDialog.findViewById(R.id.mark_read);
|
||||
TextView notDisplayView = mBottomDialog.findViewById(R.id.not_display);
|
||||
TextView deleteChatView = mBottomDialog.findViewById(R.id.delete_chat);
|
||||
|
||||
if (selectSize <= 0) {
|
||||
deleteChatView.setAlpha(0.5f);
|
||||
deleteChatView.setEnabled(false);
|
||||
|
||||
notDisplayView.setAlpha(0.5f);
|
||||
notDisplayView.setEnabled(false);
|
||||
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
markReadView.setText(getString(R.string.has_all_read));
|
||||
} else {
|
||||
deleteChatView.setAlpha(1f);
|
||||
deleteChatView.setEnabled(true);
|
||||
|
||||
notDisplayView.setAlpha(1f);
|
||||
notDisplayView.setEnabled(true);
|
||||
|
||||
markReadView.setText(getString(R.string.mark_read));
|
||||
if (isShowReadButton) {
|
||||
markReadView.setAlpha(1f);
|
||||
markReadView.setEnabled(true);
|
||||
} else {
|
||||
markReadView.setAlpha(0.5f);
|
||||
markReadView.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetEditConversationStatus() {
|
||||
isShowReadAllButton = false;
|
||||
isShowReadButton = false;
|
||||
if (mBottomDialog != null) {
|
||||
mBottomDialog.dismiss();
|
||||
}
|
||||
mConversationLayout.resetTitleBar();
|
||||
}
|
||||
|
||||
private void closeEditConversationDialog() {
|
||||
if (mBottomDialog != null) {
|
||||
mBottomDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private void setConversationMenu() {
|
||||
menu = new Menu(getActivity(), mConversationLayout.getCreateChatView());
|
||||
PopActionClickListener popActionClickListener = new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int position, Object data) {
|
||||
PopMenuAction action = (PopMenuAction) data;
|
||||
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.start_conversation))) {
|
||||
TUICore.startActivity("StartC2CChatMinimalistActivity", null);
|
||||
}
|
||||
|
||||
if (TextUtils.equals(action.getActionName(), getResources().getString(R.string.create_group_chat))) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(TUIConversationConstants.GroupType.TYPE, TUIConversationConstants.GroupType.PUBLIC);
|
||||
TUICore.startActivity("StartGroupChatMinimalistActivity", bundle);
|
||||
}
|
||||
|
||||
menu.hide();
|
||||
}
|
||||
};
|
||||
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
|
||||
action.setActionName(getResources().getString(R.string.start_conversation));
|
||||
action.setActionClickListener(popActionClickListener);
|
||||
action.setIconResId(R.drawable.conversation_create_c2c);
|
||||
List<PopMenuAction> menuActions = new ArrayList<>();
|
||||
menuActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.create_group_chat));
|
||||
action.setIconResId(R.drawable.conversation_group_icon);
|
||||
action.setActionClickListener(popActionClickListener);
|
||||
menuActions.add(action);
|
||||
|
||||
menu.setMenuAction(menuActions);
|
||||
}
|
||||
|
||||
private void showConversationMoreActionDialog(ConversationInfo conversationInfo) {
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.minimalist_more_dialog, null, false);
|
||||
LinearLayout layout = view.findViewById(R.id.layout_actions);
|
||||
AlertDialog moreDialog = new AlertDialog.Builder(getContext()).setView(view).create();
|
||||
|
||||
List<ConversationPopMenuItem> itemList = getConversationPopMenuItems(conversationInfo, moreDialog);
|
||||
|
||||
for (ConversationPopMenuItem item : itemList) {
|
||||
View itemView = LayoutInflater.from(getContext()).inflate(R.layout.conversation_minimalist_pop_menu_item, null, false);
|
||||
TextView textView = itemView.findViewById(R.id.text);
|
||||
View divider = itemView.findViewById(R.id.divider);
|
||||
textView.setText(item.text);
|
||||
if (item.isAlert) {
|
||||
textView.setTextColor(0xFFFF584C);
|
||||
}
|
||||
itemView.setOnClickListener(item.onClickListener);
|
||||
if (itemList.indexOf(item) == itemList.size() - 1) {
|
||||
divider.setVisibility(View.GONE);
|
||||
}
|
||||
layout.addView(itemView);
|
||||
}
|
||||
|
||||
TextView cancelView = view.findViewById(R.id.cancel_button);
|
||||
cancelView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
moreDialog.setCanceledOnTouchOutside(false);
|
||||
Window win = moreDialog.getWindow();
|
||||
WindowManager.LayoutParams lp = win.getAttributes();
|
||||
lp.width = lp.width - ScreenUtil.getPxByDp(16f);
|
||||
lp.y = ScreenUtil.getPxByDp(34f);
|
||||
moreDialog.getWindow().setBackgroundDrawableResource(com.tencent.qcloud.tuikit.timcommon.R.color.status_bar_color);
|
||||
win.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
|
||||
win.setAttributes(lp);
|
||||
moreDialog.show();
|
||||
|
||||
moreDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private List<ConversationPopMenuItem> getConversationPopMenuItems(ConversationInfo conversationInfo, AlertDialog moreDialog) {
|
||||
List<ConversationPopMenuItem> itemList = new ArrayList<>();
|
||||
ConversationPopMenuItem pinItem = new ConversationPopMenuItem();
|
||||
if (conversationInfo.isTop()) {
|
||||
pinItem.text = getString(R.string.quit_chat_top);
|
||||
} else {
|
||||
pinItem.text = getString(R.string.chat_top);
|
||||
}
|
||||
pinItem.onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.setConversationTop(conversationInfo, new IUIKitCallback() {
|
||||
@Override
|
||||
public void onSuccess(Object data) {
|
||||
super.onSuccess(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
super.onError(module, errCode, errMsg);
|
||||
}
|
||||
});
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
};
|
||||
itemList.add(pinItem);
|
||||
|
||||
ConversationPopMenuItem hideItem = new ConversationPopMenuItem();
|
||||
hideItem.text = getString(R.string.not_display);
|
||||
hideItem.onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.markConversationHidden(conversationInfo);
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
};
|
||||
itemList.add(hideItem);
|
||||
ConversationPopMenuItem clearHistoryItem = new ConversationPopMenuItem();
|
||||
clearHistoryItem.text = getString(R.string.clear_message);
|
||||
clearHistoryItem.onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.clearConversationMessage(conversationInfo);
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
mConversationLayout.markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
};
|
||||
itemList.add(clearHistoryItem);
|
||||
ConversationPopMenuItem deleteItem = new ConversationPopMenuItem();
|
||||
deleteItem.text = getString(R.string.chat_delete);
|
||||
deleteItem.isAlert = true;
|
||||
deleteItem.onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mConversationLayout.deleteConversation(conversationInfo);
|
||||
moreDialog.dismiss();
|
||||
}
|
||||
};
|
||||
itemList.add(deleteItem);
|
||||
|
||||
TUIConversationConfigMinimalist.ConversationMenuItemDataSource dataSource = TUIConversationConfigMinimalist.getConversationMenuItemDataSource();
|
||||
if (dataSource != null) {
|
||||
List<Integer> excludeList = dataSource.conversationShouldHideItemsInMoreMenu(conversationInfo);
|
||||
if (excludeList != null && !excludeList.isEmpty()) {
|
||||
if (excludeList.contains(TUIConversationConfigMinimalist.PIN)) {
|
||||
itemList.remove(pinItem);
|
||||
}
|
||||
if (excludeList.contains(TUIConversationConfigMinimalist.HIDE)) {
|
||||
itemList.remove(hideItem);
|
||||
}
|
||||
if (excludeList.contains(TUIConversationConfigMinimalist.CLEAR)) {
|
||||
itemList.remove(clearHistoryItem);
|
||||
}
|
||||
if (excludeList.contains(TUIConversationConfigMinimalist.DELETE)) {
|
||||
itemList.remove(deleteItem);
|
||||
}
|
||||
}
|
||||
List<ConversationPopMenuItem> conversationPopMenuItems = dataSource.conversationShouldAddNewItemsToMoreMenu(conversationInfo);
|
||||
if (conversationPopMenuItems != null && !conversationPopMenuItems.isEmpty()) {
|
||||
itemList.addAll(conversationPopMenuItems);
|
||||
}
|
||||
}
|
||||
return itemList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (unreadCountReceiver != null) {
|
||||
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(unreadCountReceiver);
|
||||
unreadCountReceiver = null;
|
||||
}
|
||||
|
||||
if (presenter != null) {
|
||||
presenter.destroy();
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.activities.BaseMinimalistLightActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
|
||||
public class TUIFoldedConversationMinimalistActivity extends BaseMinimalistLightActivity {
|
||||
private TUIFoldedConversationMinimalistFragment mTUIFoldedConversationMinimalistFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.conversation_folded_activity);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mTUIFoldedConversationMinimalistFragment = new TUIFoldedConversationMinimalistFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, mTUIFoldedConversationMinimalistFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopActionClickListener;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopDialogAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.ITitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIFoldedConversationMinimalistFragment extends Fragment {
|
||||
private View mBaseView;
|
||||
private TitleBarLayout mTitleBarLayout;
|
||||
private FoldedConversationLayout mFoldedLayout;
|
||||
private PopDialogAdapter mConversationPopAdapter;
|
||||
private ListView mConversationPopList;
|
||||
private PopupWindow mConversationPopWindow;
|
||||
private String popWindowConversationId;
|
||||
private List<PopMenuAction> mConversationPopActions = new ArrayList<>();
|
||||
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalist_folded_fragment, container, false);
|
||||
initView();
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mFoldedLayout = mBaseView.findViewById(R.id.folded_conversation_layout);
|
||||
mTitleBarLayout = mFoldedLayout.getTitleBar();
|
||||
mTitleBarLayout.setTitle(getResources().getString(R.string.folded_group_chat), ITitleBarLayout.Position.MIDDLE);
|
||||
mTitleBarLayout.setOnLeftClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
presenter = new ConversationFoldPresenter();
|
||||
presenter.initListener();
|
||||
|
||||
mFoldedLayout.setPresenter(presenter);
|
||||
mFoldedLayout.initDefault();
|
||||
|
||||
mFoldedLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
TUIConversationUtils.startChatActivity(conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {
|
||||
showItemPopMenu(view, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {
|
||||
if (dataSource == null) {
|
||||
return;
|
||||
}
|
||||
ConversationInfo conversationInfo = dataSource.get(0);
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(popWindowConversationId) && popWindowConversationId.equals(conversationInfo.getConversationId())) {
|
||||
if (mConversationPopWindow != null) {
|
||||
mConversationPopWindow.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {
|
||||
if (conversationInfo == null) {
|
||||
popWindowConversationId = "";
|
||||
return;
|
||||
}
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
}
|
||||
});
|
||||
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
|
||||
private void initPopMenuAction() {
|
||||
|
||||
List<PopMenuAction> conversationPopActions = new ArrayList<PopMenuAction>();
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionName(getResources().getString(R.string.not_display));
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
ConversationInfo conversationInfo = (ConversationInfo) data;
|
||||
mFoldedLayout.markConversationHidden(conversationInfo);
|
||||
}
|
||||
});
|
||||
conversationPopActions.add(action);
|
||||
|
||||
action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.deleteConversation((ConversationInfo) data);
|
||||
}
|
||||
});
|
||||
action.setActionName(getResources().getString(R.string.chat_delete));
|
||||
conversationPopActions.add(action);
|
||||
|
||||
mConversationPopActions.clear();
|
||||
mConversationPopActions.addAll(conversationPopActions);
|
||||
}
|
||||
|
||||
private void restoreConversationItemBackground() {
|
||||
if (mFoldedLayout.getConversationList().getAdapter() != null && mFoldedLayout.getConversationList().getAdapter().isClick()) {
|
||||
mFoldedLayout.getConversationList().getAdapter().setClick(false);
|
||||
mFoldedLayout.getConversationList().getAdapter().notifyItemChanged(mFoldedLayout.getConversationList().getAdapter().getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void addMarkUnreadPopMenuAction(boolean markUnread) {
|
||||
PopMenuAction action = new PopMenuAction();
|
||||
action.setActionClickListener(new PopActionClickListener() {
|
||||
@Override
|
||||
public void onActionClick(int index, Object data) {
|
||||
mFoldedLayout.markConversationUnread((ConversationInfo) data, markUnread);
|
||||
}
|
||||
});
|
||||
if (markUnread) {
|
||||
action.setActionName(getResources().getString(R.string.mark_unread));
|
||||
} else {
|
||||
action.setActionName(getResources().getString(R.string.mark_read));
|
||||
}
|
||||
mConversationPopActions.add(0, action);
|
||||
}
|
||||
|
||||
private void showItemPopMenu(View view, final ConversationInfo conversationInfo) {
|
||||
initPopMenuAction();
|
||||
|
||||
if (conversationInfo.getUnRead() > 0) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
addMarkUnreadPopMenuAction(false);
|
||||
} else {
|
||||
addMarkUnreadPopMenuAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
View itemPop = LayoutInflater.from(getActivity()).inflate(R.layout.conversation_pop_menu_layout, null);
|
||||
mConversationPopList = itemPop.findViewById(R.id.pop_menu_list);
|
||||
mConversationPopList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = mConversationPopActions.get(position);
|
||||
if (action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, conversationInfo);
|
||||
}
|
||||
mConversationPopWindow.dismiss();
|
||||
restoreConversationItemBackground();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < mConversationPopActions.size(); i++) {
|
||||
PopMenuAction action = mConversationPopActions.get(i);
|
||||
if (conversationInfo.isTop()) {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.quit_chat_top));
|
||||
}
|
||||
} else {
|
||||
if (action.getActionName().equals(getResources().getString(R.string.quit_chat_top))) {
|
||||
action.setActionName(getResources().getString(R.string.chat_top));
|
||||
}
|
||||
}
|
||||
}
|
||||
mConversationPopAdapter = new PopDialogAdapter();
|
||||
mConversationPopList.setAdapter(mConversationPopAdapter);
|
||||
mConversationPopAdapter.setDataSource(mConversationPopActions);
|
||||
mConversationPopWindow = new PopupWindow(itemPop, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
mConversationPopWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
mConversationPopWindow.setOutsideTouchable(true);
|
||||
popWindowConversationId = conversationInfo.getConversationId();
|
||||
int width = ConversationUtils.getListUnspecifiedWidth(mConversationPopAdapter, mConversationPopList);
|
||||
mConversationPopWindow.setWidth(width);
|
||||
mConversationPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
restoreConversationItemBackground();
|
||||
popWindowConversationId = "";
|
||||
}
|
||||
});
|
||||
int x = view.getWidth() / 2;
|
||||
int y = -view.getHeight() / 3;
|
||||
int popHeight = ScreenUtil.dip2px(45) * 3;
|
||||
if (y + popHeight + view.getY() + view.getHeight() > mFoldedLayout.getBottom()) {
|
||||
y = y - popHeight;
|
||||
}
|
||||
mConversationPopWindow.showAsDropDown(view, x, y, Gravity.TOP | Gravity.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (presenter != null) {
|
||||
presenter.destroy();
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
|
||||
public class TUIForwardSelectMinimalistActivity extends AppCompatActivity {
|
||||
private static final String TAG = TUIForwardSelectMinimalistActivity.class.getSimpleName();
|
||||
|
||||
private TUIForwardSelectMinimalistFragment forwardSelectMinimalistFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.conversation_forward_activity_layout);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
TUIConversationLog.i(TAG, "onNewIntent");
|
||||
super.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
TUIConversationLog.i(TAG, "onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
forwardSelectMinimalistFragment = new TUIForwardSelectMinimalistFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, forwardSelectMinimalistFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationConstants;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ForwardSelectLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class TUIForwardSelectMinimalistFragment extends Fragment {
|
||||
private static final String TAG = TUIForwardSelectMinimalistFragment.class.getSimpleName();
|
||||
|
||||
private View mBaseView;
|
||||
private ForwardSelectLayout mForwardLayout;
|
||||
private TextView conversationNamesTv;
|
||||
private List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private View forwardListLayout;
|
||||
private TextView mSureView;
|
||||
|
||||
private ConversationPresenter presenter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
||||
mBaseView = inflater.inflate(R.layout.minimalist_forward_fragment, container, false);
|
||||
return mBaseView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
mForwardLayout = view.findViewById(R.id.forward_conversation_layout);
|
||||
conversationNamesTv = view.findViewById(R.id.conversation_name_tv);
|
||||
forwardListLayout = view.findViewById(R.id.forward_list_layout);
|
||||
|
||||
presenter = new ConversationPresenter();
|
||||
mForwardLayout.setPresenter(presenter);
|
||||
|
||||
mForwardLayout.initDefault();
|
||||
|
||||
mForwardLayout.getConversationList().setOnConversationAdapterListener(new OnConversationAdapterListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int viewType, ConversationInfo conversationInfo) {
|
||||
refreshSelectConversations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> dataSource) {}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationUnread(View view, ConversationInfo conversationInfo, boolean markUnread) {}
|
||||
|
||||
@Override
|
||||
public void onMarkConversationHidden(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onClickMoreView(View view, ConversationInfo conversationInfo) {}
|
||||
|
||||
@Override
|
||||
public void onSwipeConversationChanged(ConversationInfo conversationInfo) {}
|
||||
});
|
||||
|
||||
mSureView = view.findViewById(R.id.btn_msg_ok);
|
||||
mSureView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getActivity() != null) {
|
||||
HashMap<String, Boolean> conversationMap = new HashMap<>();
|
||||
if (mDataSource != null && !mDataSource.isEmpty()) {
|
||||
for (int i = 0; i < mDataSource.size(); i++) {
|
||||
conversationMap.put(mDataSource.get(i).getId(), mDataSource.get(i).isGroup());
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(TUIConversationConstants.FORWARD_SELECT_CONVERSATION_KEY, conversationMap);
|
||||
getActivity().setResult(TUIConversationConstants.FORWARD_SELECT_ACTIVTY_CODE, intent);
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelectConversations();
|
||||
}
|
||||
|
||||
private void refreshSelectConversations() {
|
||||
ConversationListAdapter adapter = mForwardLayout.getConversationList().getAdapter();
|
||||
if (adapter != null) {
|
||||
mDataSource = adapter.getSelectedItem();
|
||||
} else {
|
||||
mDataSource = null;
|
||||
}
|
||||
|
||||
conversationNamesTv.setText(getSelectedNames());
|
||||
if (mDataSource == null || mDataSource.isEmpty()) {
|
||||
mSureView.setVisibility(View.GONE);
|
||||
forwardListLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
forwardListLayout.setVisibility(View.VISIBLE);
|
||||
mSureView.setVisibility(View.VISIBLE);
|
||||
mSureView.setText(getString(R.string.conversation_forward) + "(" + mDataSource.size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private String getSelectedNames() {
|
||||
if (mDataSource == null || mDataSource.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
for (ConversationInfo conversationInfo : mDataSource) {
|
||||
stringBuffer.append(conversationInfo.getShowName());
|
||||
stringBuffer.append(",");
|
||||
}
|
||||
return stringBuffer.substring(0, stringBuffer.length() - 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TUIConversationUtils {
|
||||
public static void startChatActivity(ConversationInfo conversationInfo) {
|
||||
Bundle param = new Bundle();
|
||||
param.putInt(TUIConstants.TUIChat.CHAT_TYPE, conversationInfo.isGroup() ? V2TIMConversation.V2TIM_GROUP : V2TIMConversation.V2TIM_C2C);
|
||||
param.putString(TUIConstants.TUIChat.CHAT_ID, conversationInfo.getId());
|
||||
param.putString(TUIConstants.TUIChat.CHAT_NAME, conversationInfo.getTitle());
|
||||
if (conversationInfo.getDraft() != null) {
|
||||
param.putString(TUIConstants.TUIChat.DRAFT_TEXT, conversationInfo.getDraft().getDraftText());
|
||||
param.putLong(TUIConstants.TUIChat.DRAFT_TIME, conversationInfo.getDraft().getDraftTime());
|
||||
}
|
||||
param.putBoolean(TUIConstants.TUIChat.IS_TOP_CHAT, conversationInfo.isTop());
|
||||
param.putString(TUIConstants.TUIChat.FACE_URL, conversationInfo.getIconPath());
|
||||
if (conversationInfo.isGroup()) {
|
||||
param.putString(TUIConstants.TUIChat.GROUP_TYPE, conversationInfo.getGroupType());
|
||||
param.putSerializable(TUIConstants.TUIChat.FACE_URL_LIST, (Serializable) conversationInfo.getIconUrlList());
|
||||
param.putSerializable(TUIConstants.TUIChat.AT_INFO_LIST, (Serializable) conversationInfo.getGroupAtInfoList());
|
||||
}
|
||||
if (conversationInfo.isGroup()) {
|
||||
TUICore.startActivity("TUIGroupChatMinimalistActivity", param);
|
||||
} else {
|
||||
TUICore.startActivity("TUIC2CChatMinimalistActivity", param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public abstract class ConversationBaseHolder extends RecyclerView.ViewHolder {
|
||||
protected View rootView;
|
||||
protected ConversationListAdapter mAdapter;
|
||||
|
||||
public ConversationBaseHolder(View itemView) {
|
||||
super(itemView);
|
||||
rootView = itemView;
|
||||
}
|
||||
|
||||
public void setAdapter(RecyclerView.Adapter adapter) {
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
|
||||
public abstract void layoutViews(ConversationInfo conversationInfo, int position);
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.UnreadCountTextView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.face.FaceManager;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.DateTimeUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.DraftInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.minimalistui.TUIConversationConfigMinimalist;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ConversationCommonHolder extends ConversationBaseHolder {
|
||||
public ConversationIconView conversationIconView;
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected UnreadCountTextView unreadText;
|
||||
protected UnreadCountTextView conversationNotDisturbUnread;
|
||||
protected ImageView disturbView;
|
||||
protected CheckBox multiSelectCheckBox;
|
||||
protected RelativeLayout messageStatusLayout;
|
||||
public ImageView messageSending;
|
||||
public ImageView messageFailed;
|
||||
private boolean isForwardMode = false;
|
||||
protected View userStatusView;
|
||||
|
||||
protected TextView atAllTv;
|
||||
protected TextView atMeTv;
|
||||
protected TextView draftTv;
|
||||
protected TextView riskTv;
|
||||
private boolean showFoldedStyle = true;
|
||||
protected TextView foldGroupNameTv;
|
||||
protected TextView foldGroupNameDivider;
|
||||
protected SwipeLayout swipeLayout;
|
||||
protected RelativeLayout markReadView;
|
||||
protected RelativeLayout moreView;
|
||||
protected TextView markReadTextView;
|
||||
protected TextView notDisplayView;
|
||||
protected ImageView markReadIconView;
|
||||
private ConversationInfo currentConversation;
|
||||
|
||||
public ConversationCommonHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
conversationNotDisturbUnread = rootView.findViewById(R.id.conversation_not_disturb_unread);
|
||||
atMeTv = rootView.findViewById(R.id.conversation_at_me);
|
||||
atAllTv = rootView.findViewById(R.id.conversation_at_all);
|
||||
draftTv = rootView.findViewById(R.id.conversation_draft);
|
||||
riskTv = rootView.findViewById(R.id.conversation_risk);
|
||||
foldGroupNameTv = rootView.findViewById(R.id.fold_group_name);
|
||||
foldGroupNameDivider = rootView.findViewById(R.id.fold_group_name_divider);
|
||||
disturbView = rootView.findViewById(R.id.not_disturb);
|
||||
multiSelectCheckBox = rootView.findViewById(R.id.select_checkbox);
|
||||
messageStatusLayout = rootView.findViewById(R.id.message_status_layout);
|
||||
messageFailed = itemView.findViewById(R.id.message_status_failed);
|
||||
messageSending = itemView.findViewById(R.id.message_status_sending);
|
||||
userStatusView = itemView.findViewById(R.id.user_status);
|
||||
swipeLayout = itemView.findViewById(R.id.swipe);
|
||||
markReadView = itemView.findViewById(R.id.mark_read);
|
||||
moreView = itemView.findViewById(R.id.more_view);
|
||||
markReadTextView = itemView.findViewById(R.id.mark_read_text);
|
||||
notDisplayView = itemView.findViewById(R.id.not_display);
|
||||
markReadIconView = itemView.findViewById(R.id.mark_read_image);
|
||||
}
|
||||
|
||||
public void setForwardMode(boolean forwardMode) {
|
||||
isForwardMode = forwardMode;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
currentConversation = conversation;
|
||||
|
||||
initTitleAndTime(conversation);
|
||||
setLastMessageAndStatus(conversation);
|
||||
|
||||
conversationIconView.setRadius(ScreenUtil.dip2px(40));
|
||||
if (!mAdapter.hasItemUnreadDot()) {
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
conversationIconView.setShowFoldedStyle(showFoldedStyle);
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
if (conversation.isShowDisturbIcon() && !isForwardMode) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
} else {
|
||||
disturbView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
disturbView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (isForwardMode) {
|
||||
messageText.setVisibility(View.GONE);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.GONE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
atAllTv.setVisibility(View.GONE);
|
||||
atMeTv.setVisibility(View.GONE);
|
||||
draftTv.setVisibility(View.GONE);
|
||||
riskTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (!conversation.isGroup() && TUIConversationConfigMinimalist.isShowUserOnlineStatusIcon()) {
|
||||
if (conversation.getStatusType() == V2TIMUserStatus.V2TIM_USER_STATUS_ONLINE) {
|
||||
userStatusView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
applyCustomConfig();
|
||||
}
|
||||
|
||||
private void applyCustomConfig() {
|
||||
if (currentConversation.isTop() && !isForwardMode) {
|
||||
Drawable pinnedCellBackground = TUIConversationConfigMinimalist.getPinnedCellBackground();
|
||||
if (pinnedCellBackground != null) {
|
||||
leftItemLayout.setBackground(pinnedCellBackground);
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
}
|
||||
} else {
|
||||
Drawable cellBackground = TUIConversationConfigMinimalist.getCellBackground();
|
||||
if (cellBackground != null) {
|
||||
leftItemLayout.setBackground(cellBackground);
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
}
|
||||
if (!TUIConversationConfigMinimalist.isShowCellUnreadCount()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TUIConversationConfigMinimalist.isShowUserOnlineStatusIcon()) {
|
||||
userStatusView.setVisibility(View.GONE);
|
||||
}
|
||||
if (TUIConversationConfigMinimalist.getCellTitleLabelFontSize() != TUIConversationConfigMinimalist.UNDEFINED) {
|
||||
titleText.setTextSize(TUIConversationConfigMinimalist.getCellTitleLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigMinimalist.getCellSubtitleLabelFontSize() != TUIConversationConfigMinimalist.UNDEFINED) {
|
||||
messageText.setTextSize(TUIConversationConfigMinimalist.getCellSubtitleLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigMinimalist.getCellTimeLabelFontSize() != TUIConversationConfigMinimalist.UNDEFINED) {
|
||||
timelineText.setTextSize(TUIConversationConfigMinimalist.getCellTimeLabelFontSize());
|
||||
}
|
||||
if (TUIConversationConfigMinimalist.getAvatarCornerRadius() != TUIConversationConfigMinimalist.UNDEFINED) {
|
||||
conversationIconView.setRadius(TUIConversationConfigMinimalist.getAvatarCornerRadius());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setLastMessageAndStatus(ConversationInfo conversation) {
|
||||
DraftInfo draftInfo = conversation.getDraft();
|
||||
String draftText = "";
|
||||
if (draftInfo != null) {
|
||||
Gson gson = new Gson();
|
||||
HashMap draftJsonMap;
|
||||
draftText = draftInfo.getDraftText();
|
||||
try {
|
||||
draftJsonMap = gson.fromJson(draftInfo.getDraftText(), HashMap.class);
|
||||
if (draftJsonMap != null) {
|
||||
draftText = (String) draftJsonMap.get("content");
|
||||
}
|
||||
} catch (JsonSyntaxException e) {
|
||||
TUIConversationLog.e("ConversationCommonHolder", " getDraftJsonMap error ");
|
||||
}
|
||||
}
|
||||
|
||||
atAllTv.setVisibility(View.GONE);
|
||||
atMeTv.setVisibility(View.GONE);
|
||||
draftTv.setVisibility(View.GONE);
|
||||
riskTv.setVisibility(View.GONE);
|
||||
if (draftInfo != null) {
|
||||
messageText.setText(FaceManager.emojiJudge(draftText));
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(draftInfo.getDraftTime() * 1000)));
|
||||
} else {
|
||||
if (TUIConversationUtils.hasRiskContent(conversation.getLastMessage())) {
|
||||
riskTv.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
TUIMessageBean lasTUIMessageBean = conversation.getLastTUIMessageBean();
|
||||
if (lasTUIMessageBean != null) {
|
||||
String displayString = ConversationPresenter.getMessageDisplayString(lasTUIMessageBean);
|
||||
messageText.setText(displayString);
|
||||
messageText.setTextColor(rootView.getResources().getColor(R.color.list_bottom_text_bg));
|
||||
}
|
||||
if (conversation.getLastMessage() != null) {
|
||||
timelineText.setText(DateTimeUtil.getTimeFormatText(new Date(conversation.getLastMessageTime() * 1000)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conversation.isShowDisturbIcon()) {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
if ((showFoldedStyle && conversation.isMarkFold())) {
|
||||
if (conversation.isMarkLocalUnread()) {
|
||||
conversationNotDisturbUnread.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (conversation.getUnRead() == 0) {
|
||||
if (conversation.isMarkUnread()) {
|
||||
conversationNotDisturbUnread.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
conversationNotDisturbUnread.setVisibility(View.VISIBLE);
|
||||
|
||||
if (messageText.getText() != null) {
|
||||
String text = messageText.getText().toString();
|
||||
messageText.setText("[" + conversation.getUnRead() + " " + rootView.getContext().getString(R.string.message_num) + "] " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (conversation.getUnRead() > 0) {
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
conversationNotDisturbUnread.setVisibility(View.GONE);
|
||||
if (conversation.isMarkUnread()) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
unreadText.setText("1");
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ME) {
|
||||
atMeTv.setVisibility(View.VISIBLE);
|
||||
} else if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ALL) {
|
||||
atAllTv.setVisibility(View.VISIBLE);
|
||||
} else if (conversation.getAtType() == ConversationInfo.AT_TYPE_AT_ALL_AND_ME) {
|
||||
atAllTv.setVisibility(View.VISIBLE);
|
||||
atMeTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (draftInfo != null) {
|
||||
draftTv.setVisibility(View.VISIBLE);
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else {
|
||||
V2TIMMessage lastMessage = conversation.getLastMessage();
|
||||
if (lastMessage != null) {
|
||||
int status = lastMessage.getStatus();
|
||||
if (status == V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.VISIBLE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
} else if (status == V2TIMMessage.V2TIM_MSG_STATUS_SENDING) {
|
||||
messageStatusLayout.setVisibility(View.VISIBLE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
messageStatusLayout.setVisibility(View.GONE);
|
||||
messageFailed.setVisibility(View.GONE);
|
||||
messageSending.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initTitleAndTime(ConversationInfo conversation) {
|
||||
if (showFoldedStyle && conversation.isMarkFold()) {
|
||||
titleText.setText(R.string.folded_group_chat);
|
||||
timelineText.setVisibility(View.GONE);
|
||||
foldGroupNameTv.setVisibility(View.VISIBLE);
|
||||
foldGroupNameDivider.setVisibility(View.VISIBLE);
|
||||
foldGroupNameTv.setText(conversation.getTitle());
|
||||
} else {
|
||||
titleText.setText(conversation.getTitle());
|
||||
foldGroupNameTv.setVisibility(View.GONE);
|
||||
foldGroupNameDivider.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
|
||||
public class ConversationCustomHolder extends ConversationBaseHolder {
|
||||
protected LinearLayout leftItemLayout;
|
||||
protected TextView titleText;
|
||||
protected TextView messageText;
|
||||
protected TextView timelineText;
|
||||
protected TextView unreadText;
|
||||
protected ConversationIconView conversationIconView;
|
||||
|
||||
public ConversationCustomHolder(View itemView) {
|
||||
super(itemView);
|
||||
leftItemLayout = rootView.findViewById(R.id.item_left);
|
||||
conversationIconView = rootView.findViewById(R.id.conversation_icon);
|
||||
titleText = rootView.findViewById(R.id.conversation_title);
|
||||
messageText = rootView.findViewById(R.id.conversation_last_msg);
|
||||
timelineText = rootView.findViewById(R.id.conversation_time);
|
||||
unreadText = rootView.findViewById(R.id.conversation_unread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversation, int position) {
|
||||
if (conversation.isTop()) {
|
||||
leftItemLayout.setBackgroundColor(rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
leftItemLayout.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
conversationIconView.setConversation(conversation);
|
||||
|
||||
titleText.setText(conversation.getTitle());
|
||||
messageText.setText("");
|
||||
timelineText.setText("");
|
||||
|
||||
if (conversation.getUnRead() > 0) {
|
||||
unreadText.setVisibility(View.VISIBLE);
|
||||
if (conversation.getUnRead() > 99) {
|
||||
unreadText.setText("99+");
|
||||
} else {
|
||||
unreadText.setText("" + conversation.getUnRead());
|
||||
}
|
||||
} else {
|
||||
unreadText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.gatherimage.SynthesizedImageView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ImageUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.TUIUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ThreadUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationIconPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationIconView extends RelativeLayout {
|
||||
private ImageView mIconView;
|
||||
private boolean showFoldedStyle = false;
|
||||
|
||||
private ConversationIconPresenter presenter;
|
||||
|
||||
public ConversationIconView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationIconView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), com.tencent.qcloud.tuikit.timcommon.R.layout.common_profile_icon_view, this);
|
||||
mIconView = findViewById(com.tencent.qcloud.tuikit.timcommon.R.id.profile_icon);
|
||||
((SynthesizedImageView) mIconView).defaultImage(TUIConfig.getDefaultAvatarImage());
|
||||
presenter = new ConversationIconPresenter();
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* url
|
||||
*
|
||||
* @param iconUrls url,9
|
||||
*/
|
||||
public void setIconUrls(final List<Object> iconUrls, final String conversationId) {
|
||||
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).displayImage(iconUrls).load(conversationId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversation(ConversationInfo conversationInfo) {
|
||||
if (showFoldedStyle && conversationInfo.isMarkFold()) {
|
||||
mIconView.setImageResource(R.drawable.conversation_ic_fold);
|
||||
} else if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setImageId(conversationInfo.getConversationId());
|
||||
if (conversationInfo.isGroup()) {
|
||||
fillConversationUrlForGroup(conversationInfo);
|
||||
} else {
|
||||
setIconUrls(conversationInfo.getIconUrlList(), conversationInfo.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillConversationUrlForGroup(final ConversationInfo info) {
|
||||
List<Object> iconUrlList = info.getIconUrlList();
|
||||
if (iconUrlList == null || iconUrlList.size() == 0) {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar()) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadUtils.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String savedIcon = ImageUtil.getGroupConversationAvatar(info.getConversationId());
|
||||
if (TextUtils.isEmpty(savedIcon)) {
|
||||
fillFaceUrlList(info.getId(), info);
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(savedIcon);
|
||||
info.setIconUrlList(list);
|
||||
setIconUrls(list, info.getConversationId());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!TUIConfig.isEnableGroupGridAvatar() && iconUrlList.size() > 1) {
|
||||
List<Object> faceList = new ArrayList<>();
|
||||
faceList.add(TUIConfig.getDefaultGroupAvatarImage());
|
||||
setIconUrls(faceList, info.getConversationId());
|
||||
} else {
|
||||
setIconUrls(iconUrlList, info.getConversationId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFaceUrlList(final String groupID, final ConversationInfo info) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearImage();
|
||||
presenter.getGroupMemberIconList(groupID, new IUIKitCallback<List<Object>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Object> data) {
|
||||
info.setIconUrlList(data);
|
||||
setIconUrls(data, info.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).defaultImage(TUIUtil.getDefaultGroupIconResIDByGroupType(getContext(), info.getGroupType()));
|
||||
}
|
||||
|
||||
setIconUrls(null, info.getConversationId());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setRadius(int radius) {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) (mIconView)).setRadius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultImageResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
mIconView.setImageBitmap(bd.getBitmap());
|
||||
}
|
||||
|
||||
public void setBitmapResId(int resId) {
|
||||
BitmapDrawable bd = (BitmapDrawable) getContext().getResources().getDrawable(resId);
|
||||
Bitmap bitmap = ImageUtil.toRoundBitmap(bd.getBitmap());
|
||||
mIconView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
public void clearImage() {
|
||||
if (mIconView instanceof SynthesizedImageView) {
|
||||
((SynthesizedImageView) mIconView).clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import com.tencent.qcloud.tuicore.TUIConfig;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.swipe.Attributes;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.minimalistui.TUIConversationConfigMinimalist;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.page.TUIConversationMinimalistFragment;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private ConversationListLayout mConversationList;
|
||||
private ViewGroup headerContainer;
|
||||
private ConversationPresenter presenter;
|
||||
private ImageView createChatView;
|
||||
private TextView conversationEditView;
|
||||
private TextView conversationEditDoneView;
|
||||
private TUIConversationMinimalistFragment.OnClickListener mClickListener = null;
|
||||
private boolean isMultiSelected = false;
|
||||
private List<ConversationInfo> mSelectConversations = new ArrayList<>();
|
||||
private ImageView homeView;
|
||||
private TextView titleView;
|
||||
private TextView rtCubeTitleView;
|
||||
|
||||
public ConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (mConversationList != null) {
|
||||
mConversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalistui_conversation_layout, this);
|
||||
mConversationList = findViewById(R.id.conversation_list);
|
||||
headerContainer = findViewById(R.id.search_layout);
|
||||
conversationEditView = findViewById(R.id.edit_button);
|
||||
createChatView = findViewById(R.id.create_new_button);
|
||||
conversationEditDoneView = findViewById(R.id.edit_done);
|
||||
mSelectConversations.clear();
|
||||
homeView = findViewById(R.id.home_rtcube);
|
||||
titleView = findViewById(R.id.title);
|
||||
rtCubeTitleView = findViewById(R.id.title_rtcube);
|
||||
conversationEditView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onEditConversationStartClick();
|
||||
}
|
||||
conversationEditView.setVisibility(GONE);
|
||||
conversationEditDoneView.setVisibility(VISIBLE);
|
||||
createChatView.setVisibility(GONE);
|
||||
|
||||
conversationMutiSelectStart();
|
||||
}
|
||||
});
|
||||
createChatView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onStartChatClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
conversationEditDoneView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mClickListener != null) {
|
||||
mClickListener.onEditConversationEndClick();
|
||||
}
|
||||
conversationEditView.setVisibility(VISIBLE);
|
||||
conversationEditDoneView.setVisibility(GONE);
|
||||
createChatView.setVisibility(VISIBLE);
|
||||
|
||||
conversationMutiSelectEnd();
|
||||
}
|
||||
});
|
||||
|
||||
applyCustomConfig();
|
||||
}
|
||||
|
||||
private void applyCustomConfig() {
|
||||
Drawable listBackground = TUIConversationConfigMinimalist.getListBackground();
|
||||
if (listBackground != null) {
|
||||
mConversationList.setBackground(listBackground);
|
||||
}
|
||||
}
|
||||
|
||||
public void initUI() {
|
||||
if (TUIConfig.getTUIHostType() != TUIConfig.TUI_HOST_TYPE_RTCUBE) {
|
||||
homeView.setVisibility(GONE);
|
||||
titleView.setVisibility(VISIBLE);
|
||||
rtCubeTitleView.setVisibility(GONE);
|
||||
} else {
|
||||
homeView.setVisibility(VISIBLE);
|
||||
titleView.setVisibility(GONE);
|
||||
rtCubeTitleView.setVisibility(VISIBLE);
|
||||
homeView.setBackgroundResource(com.tencent.qcloud.tuikit.timcommon.R.drawable.common_title_bar_home_icon);
|
||||
homeView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(TUIConstants.TIMAppKit.BACK_TO_RTCUBE_DEMO_TYPE_KEY, TUIConstants.TIMAppKit.BACK_TO_RTCUBE_DEMO_TYPE_IM);
|
||||
TUICore.startActivity("TRTCMainActivity", bundle);
|
||||
if (mClickListener != null) {
|
||||
mClickListener.finishActivity();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ImageView getCreateChatView() {
|
||||
return createChatView;
|
||||
}
|
||||
|
||||
public void resetTitleBar() {
|
||||
conversationEditView.setVisibility(VISIBLE);
|
||||
conversationEditDoneView.setVisibility(GONE);
|
||||
createChatView.setVisibility(VISIBLE);
|
||||
conversationMutiSelectEnd();
|
||||
}
|
||||
|
||||
public void setOnClickListener(TUIConversationMinimalistFragment.OnClickListener listener) {
|
||||
mClickListener = listener;
|
||||
}
|
||||
|
||||
public boolean isMultiSelected() {
|
||||
return isMultiSelected;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
titleView.setText(title);
|
||||
}
|
||||
|
||||
private void conversationMutiSelectStart() {
|
||||
ConversationListAdapter adapter = mConversationList.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.setShowMultiSelectCheckBox(true);
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.closeAllSwipeItems();
|
||||
adapter.switchAllSwipeEnable(false);
|
||||
}
|
||||
isMultiSelected = true;
|
||||
mSelectConversations.clear();
|
||||
}
|
||||
|
||||
private void conversationMutiSelectEnd() {
|
||||
ConversationListAdapter adapter = mConversationList.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.setShowMultiSelectCheckBox(false);
|
||||
adapter.notifyDataSetChanged();
|
||||
adapter.closeAllSwipeItems();
|
||||
adapter.switchAllSwipeEnable(true);
|
||||
}
|
||||
isMultiSelected = false;
|
||||
mSelectConversations.clear();
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
if (presenter != null) {
|
||||
initHeaderView();
|
||||
adapter.setShowFoldedStyle(true);
|
||||
}
|
||||
|
||||
mConversationList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
adapter.setMode(Attributes.Mode.Single);
|
||||
mConversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
mConversationList.loadConversation();
|
||||
mConversationList.loadMarkedConversation();
|
||||
}
|
||||
|
||||
public void initHeaderView() {
|
||||
headerContainer.setVisibility(VISIBLE);
|
||||
TUICore.raiseExtension(TUIConstants.TUIConversation.Extension.ConversationListHeader.MINIMALIST_EXTENSION_ID, headerContainer, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getConversationList() {
|
||||
return mConversationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {
|
||||
if (presenter != null) {
|
||||
presenter.setConversationTop(conversation, callBack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.clearConversationMessage(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnreadAndCleanUnreadCount(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {
|
||||
if (presenter != null) {
|
||||
presenter.hideFoldItem(needHide);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {
|
||||
if (presenter != null) {
|
||||
presenter.setUnreadStatusOfFoldItem(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.swipe.RecyclerSwipeAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.swipe.SimpleSwipeListener;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationListAdapter extends RecyclerSwipeAdapter<RecyclerView.ViewHolder> implements IConversationListAdapter {
|
||||
public static final int ITEM_TYPE_HEADER_HIDE = 101;
|
||||
public static final int ITEM_TYPE_FOOTER_LOADING = -99;
|
||||
public static final int HEADER_COUNT = 1;
|
||||
public static final int FOOTER_COUNT = 1;
|
||||
public static final int SELECT_COUNT = 1;
|
||||
public static final int SELECT_LABEL_COUNT = 1;
|
||||
|
||||
private boolean mHasShowUnreadDot = true;
|
||||
protected List<ConversationInfo> mDataSource = new ArrayList<>();
|
||||
private OnConversationAdapterListener mOnConversationAdapterListener;
|
||||
|
||||
private final HashMap<String, Boolean> mSelectedPositions = new HashMap<>();
|
||||
private boolean isShowMultiSelectCheckBox = false;
|
||||
private boolean isForwardFragment = false;
|
||||
|
||||
private boolean mIsLoading = false;
|
||||
|
||||
private boolean isClick = false;
|
||||
private int currentPosition = -1;
|
||||
|
||||
private boolean showFoldedStyle = true;
|
||||
|
||||
public ConversationListAdapter() {}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public boolean isClick() {
|
||||
return isClick;
|
||||
}
|
||||
|
||||
public void setClick(boolean click) {
|
||||
isClick = click;
|
||||
}
|
||||
|
||||
public void setCurrentPosition(int currentPosition, boolean isClick) {
|
||||
this.currentPosition = currentPosition;
|
||||
this.isClick = isClick;
|
||||
}
|
||||
|
||||
public void setShowMultiSelectCheckBox(boolean show) {
|
||||
isShowMultiSelectCheckBox = show;
|
||||
|
||||
if (!isShowMultiSelectCheckBox) {
|
||||
mSelectedPositions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForwardFragment(boolean forwardFragment) {
|
||||
isForwardFragment = forwardFragment;
|
||||
}
|
||||
|
||||
public void setShowFoldedStyle(boolean showFoldedStyle) {
|
||||
this.showFoldedStyle = showFoldedStyle;
|
||||
}
|
||||
|
||||
public void setItemChecked(String conversationId, boolean isChecked) {
|
||||
mSelectedPositions.put(conversationId, isChecked);
|
||||
}
|
||||
|
||||
private boolean isItemChecked(String id) {
|
||||
if (mSelectedPositions.size() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSelectedPositions.containsKey(id)) {
|
||||
return mSelectedPositions.get(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConversationInfo> getSelectedItem() {
|
||||
if (mSelectedPositions.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
List<ConversationInfo> selectList = new ArrayList<>();
|
||||
for (int i = 0; i < getItemCount() - 1; i++) {
|
||||
ConversationInfo conversationInfo = getItem(i);
|
||||
if (conversationInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if (isItemChecked(conversationInfo.getConversationId())) {
|
||||
selectList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
return selectList;
|
||||
}
|
||||
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
this.mOnConversationAdapterListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataSourceChanged(List<ConversationInfo> dataSource) {
|
||||
this.mDataSource = dataSource;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
ConversationBaseHolder holder = null;
|
||||
|
||||
View view;
|
||||
|
||||
if (viewType == ITEM_TYPE_HEADER_HIDE) {
|
||||
|
||||
return new HeaderViewHolder(new View(parent.getContext()));
|
||||
} else if (viewType == ConversationInfo.TYPE_CUSTOM) {
|
||||
view = inflater.inflate(R.layout.conversation_custom_adapter, parent, false);
|
||||
holder = new ConversationCustomHolder(view);
|
||||
} else if (viewType == ITEM_TYPE_FOOTER_LOADING) {
|
||||
view = inflater.inflate(R.layout.conversation_loading_progress_bar, parent, false);
|
||||
return new FooterViewHolder(view);
|
||||
} else if (viewType == ConversationInfo.TYPE_RECENT_LABEL) {
|
||||
view = inflater.inflate(R.layout.conversation_minimalist_forward_label_adapter, parent, false);
|
||||
return new ForwardLabelHolder(view);
|
||||
} else {
|
||||
if (isForwardFragment) {
|
||||
view = inflater.inflate(R.layout.minimalistui_conversation_forward_list_item_layout, parent, false);
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.minimalistui_conversation_list_item_layout, parent, false);
|
||||
}
|
||||
holder = new ConversationCommonHolder(view);
|
||||
((ConversationCommonHolder) holder).setForwardMode(isForwardFragment);
|
||||
((ConversationCommonHolder) holder).setShowFoldedStyle(showFoldedStyle);
|
||||
}
|
||||
holder.setAdapter(this);
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
final ConversationInfo conversationInfo = getItem(position);
|
||||
ConversationBaseHolder baseHolder = null;
|
||||
if (conversationInfo != null) {
|
||||
baseHolder = (ConversationBaseHolder) holder;
|
||||
}
|
||||
|
||||
switch (getItemViewType(position)) {
|
||||
case ConversationInfo.TYPE_CUSTOM:
|
||||
case ConversationInfo.TYPE_RECENT_LABEL:
|
||||
break;
|
||||
case ITEM_TYPE_FOOTER_LOADING: {
|
||||
if (holder instanceof FooterViewHolder) {
|
||||
((ConversationBaseHolder) holder).layoutViews(null, position);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (baseHolder instanceof ConversationCommonHolder) {
|
||||
ConversationCommonHolder viewHolder = (ConversationCommonHolder) baseHolder;
|
||||
viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);
|
||||
if (conversationInfo.isMarkFold()) {
|
||||
viewHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
|
||||
@Override
|
||||
public void onDoubleClick(SwipeLayout layout, boolean surface) {}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(viewHolder.itemView, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.markReadView.setVisibility(View.GONE);
|
||||
viewHolder.moreView.setVisibility(View.GONE);
|
||||
viewHolder.notDisplayView.setVisibility(View.VISIBLE);
|
||||
viewHolder.notDisplayView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onMarkConversationHidden(view, conversationInfo);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
mItemManger.bind(viewHolder.itemView, position);
|
||||
} else {
|
||||
viewHolder.notDisplayView.setVisibility(View.GONE);
|
||||
viewHolder.markReadView.setVisibility(View.VISIBLE);
|
||||
viewHolder.moreView.setVisibility(View.VISIBLE);
|
||||
viewHolder.swipeLayout.addSwipeListener(new SimpleSwipeListener() {
|
||||
@Override
|
||||
public void onOpen(SwipeLayout layout) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onSwipeConversationChanged(conversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(SwipeLayout layout) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onSwipeConversationChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartOpen(SwipeLayout layout) {
|
||||
int unReadNum = conversationInfo.getUnRead();
|
||||
boolean isMarkUnread = conversationInfo.isMarkUnread();
|
||||
if (unReadNum > 0) {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_read);
|
||||
viewHolder.markReadView.setBackgroundColor(viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_all_read);
|
||||
} else {
|
||||
if (isMarkUnread) {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_read);
|
||||
viewHolder.markReadView.setBackgroundColor(
|
||||
viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_all_read);
|
||||
} else {
|
||||
viewHolder.markReadTextView.setText(R.string.mark_unread);
|
||||
viewHolder.markReadView.setBackgroundColor(
|
||||
viewHolder.itemView.getResources().getColor(R.color.conversation_mark_swipe_dark_bg));
|
||||
viewHolder.markReadIconView.setBackgroundResource(R.drawable.conversation_minimalist_message_status_send_no_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
viewHolder.swipeLayout.setOnDoubleClickListener(new SwipeLayout.DoubleClickListener() {
|
||||
@Override
|
||||
public void onDoubleClick(SwipeLayout layout, boolean surface) {}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(viewHolder.itemView, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.markReadView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
boolean markRead =
|
||||
TUIConversationService.getAppContext().getString(R.string.mark_read).equals(viewHolder.markReadTextView.getText());
|
||||
mOnConversationAdapterListener.onMarkConversationUnread(view, conversationInfo, !markRead);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.moreView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onClickMoreView(view, conversationInfo);
|
||||
}
|
||||
mItemManger.closeAllSwipeItems();
|
||||
}
|
||||
});
|
||||
|
||||
mItemManger.bind(viewHolder.itemView, position);
|
||||
}
|
||||
} else {
|
||||
setOnClickListener(holder, getItemViewType(position), conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (baseHolder != null) {
|
||||
baseHolder.layoutViews(conversationInfo, position);
|
||||
setCheckBoxStatus(conversationInfo, position, baseHolder);
|
||||
}
|
||||
|
||||
if (getCurrentPosition() == position && isClick()) {
|
||||
baseHolder.itemView.setBackgroundResource(R.color.conversation_item_clicked_color);
|
||||
} else {
|
||||
if (conversationInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (conversationInfo.isTop() && !isForwardFragment) {
|
||||
baseHolder.itemView.setBackgroundColor(baseHolder.rootView.getResources().getColor(R.color.conversation_item_top_color));
|
||||
} else {
|
||||
baseHolder.itemView.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setOnClickListener(RecyclerView.ViewHolder holder, int viewType, ConversationInfo conversationInfo) {
|
||||
if (holder instanceof HeaderViewHolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mOnConversationAdapterListener.onItemClick(view, viewType, conversationInfo);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
mOnConversationAdapterListener.onItemLongClick(view, conversationInfo);
|
||||
int position = getIndexInAdapter(conversationInfo);
|
||||
if (position != -1) {
|
||||
setCurrentPosition(position, true);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setCheckBoxStatus(final ConversationInfo conversationInfo, int position, ConversationBaseHolder baseHolder) {
|
||||
if (!(baseHolder instanceof ConversationCommonHolder) || ((ConversationCommonHolder) baseHolder).multiSelectCheckBox == null) {
|
||||
return;
|
||||
}
|
||||
int viewType = getItemViewType(position);
|
||||
String conversationId = conversationInfo.getConversationId();
|
||||
ConversationCommonHolder commonHolder = (ConversationCommonHolder) baseHolder;
|
||||
if (!isShowMultiSelectCheckBox || conversationInfo.isMarkFold()) {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.GONE);
|
||||
baseHolder.itemView.setOnClickListener(null);
|
||||
} else {
|
||||
commonHolder.multiSelectCheckBox.setVisibility(View.VISIBLE);
|
||||
|
||||
commonHolder.multiSelectCheckBox.setChecked(isItemChecked(conversationId));
|
||||
|
||||
commonHolder.multiSelectCheckBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
baseHolder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(conversationId, !isItemChecked(conversationId));
|
||||
int currentPosition = getIndexInAdapter(conversationInfo);
|
||||
if (currentPosition != -1) {
|
||||
notifyItemChanged(currentPosition);
|
||||
}
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onItemClick(v, viewType, conversationInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndexInAdapter(ConversationInfo conversationInfo) {
|
||||
int position = -1;
|
||||
if (mDataSource != null) {
|
||||
int indexInData = mDataSource.indexOf(conversationInfo);
|
||||
if (indexInData != -1) {
|
||||
position = getItemIndexInAdapter(indexInData);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
|
||||
|
||||
if (holder instanceof ConversationCommonHolder) {
|
||||
((ConversationCommonHolder) holder).conversationIconView.clearImage();
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationInfo getItem(int position) {
|
||||
if (mDataSource.isEmpty() || position == getItemCount() - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int dataPosition;
|
||||
if (isForwardFragment) {
|
||||
dataPosition = position - SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
dataPosition = position - HEADER_COUNT;
|
||||
}
|
||||
if (dataPosition < mDataSource.size() && dataPosition >= 0) {
|
||||
return mDataSource.get(dataPosition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int listSize = mDataSource.size();
|
||||
if (isForwardFragment) {
|
||||
return listSize + SELECT_LABEL_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
return listSize + HEADER_COUNT + FOOTER_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (isForwardFragment) {
|
||||
if (position == 0) {
|
||||
return ConversationInfo.TYPE_RECENT_LABEL;
|
||||
}
|
||||
} else {
|
||||
if (position == 0) {
|
||||
return ITEM_TYPE_HEADER_HIDE;
|
||||
}
|
||||
}
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_TYPE_FOOTER_LOADING;
|
||||
} else if (mDataSource != null) {
|
||||
ConversationInfo conversationInfo = getItem(position);
|
||||
if (conversationInfo != null) {
|
||||
return conversationInfo.getType();
|
||||
}
|
||||
}
|
||||
return ConversationInfo.TYPE_COMMON;
|
||||
}
|
||||
|
||||
private int getItemIndexInAdapter(int index) {
|
||||
int itemIndex;
|
||||
if (isForwardFragment) {
|
||||
itemIndex = index + SELECT_LABEL_COUNT;
|
||||
} else {
|
||||
itemIndex = index + HEADER_COUNT;
|
||||
}
|
||||
return itemIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRemoved(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemRemoved(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemInserted(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemInserted(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemChanged(int position) {
|
||||
int itemIndex = getItemIndexInAdapter(position);
|
||||
notifyItemChanged(itemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMoved(int fromPosition, int toPosition) {
|
||||
int fromIndex = getItemIndexInAdapter(fromPosition);
|
||||
int toIndex = getItemIndexInAdapter(toPosition);
|
||||
notifyItemMoved(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRangeChanged(int startPosition, int count) {
|
||||
int itemStartIndex = getItemIndexInAdapter(startPosition);
|
||||
notifyItemRangeChanged(itemStartIndex, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
if (mOnConversationAdapterListener != null) {
|
||||
mOnConversationAdapterListener.onConversationChanged(conversationInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mHasShowUnreadDot = !flag;
|
||||
}
|
||||
|
||||
public boolean hasItemUnreadDot() {
|
||||
return mHasShowUnreadDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChanged(boolean isLoading) {
|
||||
this.mIsLoading = isLoading;
|
||||
notifyItemChanged(getItemCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewNeedRefresh() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwipeLayoutResourceId(int position) {
|
||||
return R.id.swipe;
|
||||
}
|
||||
|
||||
// header
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public HeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
// footer
|
||||
class FooterViewHolder extends ConversationBaseHolder {
|
||||
|
||||
public FooterViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) rootView.getLayoutParams();
|
||||
if (mIsLoading) {
|
||||
param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
|
||||
param.width = LinearLayout.LayoutParams.MATCH_PARENT;
|
||||
rootView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
param.height = 0;
|
||||
param.width = 0;
|
||||
rootView.setVisibility(View.GONE);
|
||||
}
|
||||
rootView.setLayoutParams(param);
|
||||
}
|
||||
}
|
||||
|
||||
static class ForwardLabelHolder extends ConversationBaseHolder {
|
||||
|
||||
public ForwardLabelHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutViews(ConversationInfo conversationInfo, int position) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public ConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(int state) {
|
||||
super.onScrollStateChanged(state);
|
||||
if (state == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (layoutManager == null) {
|
||||
return;
|
||||
}
|
||||
int lastPosition = layoutManager.findLastCompletelyVisibleItemPosition();
|
||||
|
||||
if (mAdapter != null) {
|
||||
if (lastPosition == mAdapter.getItemCount() - 1 && !isLoadCompleted()) {
|
||||
mAdapter.onLoadingStateChanged(true);
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadMarkedConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadMarkedConversation();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLoadCompleted() {
|
||||
if (presenter != null) {
|
||||
return presenter.isLoadFinished();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.TitleBarLayout;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationLayout extends RelativeLayout implements IConversationLayout {
|
||||
private TitleBarLayout titleBarLayout;
|
||||
private FoldedConversationListLayout conversationListLayout;
|
||||
private ConversationFoldPresenter presenter;
|
||||
|
||||
public FoldedConversationLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationListLayout != null) {
|
||||
conversationListLayout.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalist_folded_layout, this);
|
||||
titleBarLayout = findViewById(R.id.conversation_title);
|
||||
conversationListLayout = findViewById(R.id.folded_conversation_list);
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
conversationListLayout.setAdapter((IConversationListAdapter) adapter);
|
||||
adapter.setShowFoldedStyle(false);
|
||||
if (presenter != null) {
|
||||
presenter.setAdapter(adapter);
|
||||
}
|
||||
conversationListLayout.loadConversation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getConversationList() {
|
||||
return conversationListLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(ConversationInfo conversation, IUIKitCallback callBack) {}
|
||||
|
||||
@Override
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.deleteConversation(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(ConversationInfo conversation) {}
|
||||
|
||||
@Override
|
||||
public void markConversationHidden(ConversationInfo conversation) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationHidden(conversation, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (presenter != null) {
|
||||
presenter.markConversationUnread(conversationInfo, markUnread);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideFoldedItem(boolean needHide) {}
|
||||
|
||||
@Override
|
||||
public void clearUnreadStatusOfFoldItem() {}
|
||||
|
||||
@Override
|
||||
public TitleBarLayout getTitleBar() {
|
||||
return titleBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentLayout(Object parent) {}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.CustomLinearLayoutManager;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.IConversationListLayout;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationFoldPresenter;
|
||||
|
||||
public class FoldedConversationListLayout extends RecyclerView implements IConversationListLayout {
|
||||
private ConversationListAdapter mAdapter;
|
||||
private ConversationFoldPresenter presenter;
|
||||
private boolean isFolded = false;
|
||||
|
||||
public FoldedConversationListLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public FoldedConversationListLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationFoldPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
setLayoutFrozen(false);
|
||||
setItemViewCacheSize(0);
|
||||
setHasFixedSize(true);
|
||||
setFocusableInTouchMode(false);
|
||||
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
setLayoutManager(linearLayoutManager);
|
||||
SimpleItemAnimator animator = (SimpleItemAnimator) getItemAnimator();
|
||||
if (animator != null) {
|
||||
animator.setSupportsChangeAnimations(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(int resId) {
|
||||
setBackgroundColor(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableItemUnreadDot(boolean flag) {
|
||||
mAdapter.disableItemUnreadDot(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldedConversationListLayout getListLayout() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
if (adapter instanceof ConversationListAdapter) {
|
||||
super.setAdapter((ConversationListAdapter) adapter);
|
||||
mAdapter = (ConversationListAdapter) adapter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnConversationAdapterListener(OnConversationAdapterListener listener) {
|
||||
mAdapter.setOnConversationAdapterListener(listener);
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
if (presenter != null) {
|
||||
presenter.loadConversation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.R;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter;
|
||||
|
||||
public class ForwardSelectLayout extends RelativeLayout {
|
||||
private ConversationListLayout conversationList;
|
||||
private ConversationPresenter presenter;
|
||||
private TextView cancelButton;
|
||||
|
||||
public ForwardSelectLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ForwardSelectLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setPresenter(ConversationPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
if (conversationList != null) {
|
||||
conversationList.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.minimalist_forward_layout, this);
|
||||
conversationList = findViewById(R.id.conversation_list);
|
||||
cancelButton = findViewById(R.id.cancel_button);
|
||||
cancelButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
((Activity) getContext()).finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void initDefault() {
|
||||
final ConversationListAdapter adapter = new ConversationListAdapter();
|
||||
adapter.setForwardFragment(true);
|
||||
adapter.setShowMultiSelectCheckBox(true);
|
||||
adapter.setSwipeEnabled(false);
|
||||
conversationList.setAdapter((IConversationListAdapter) adapter);
|
||||
presenter.setAdapter(adapter);
|
||||
presenter.loadMoreConversation();
|
||||
}
|
||||
|
||||
public ConversationListLayout getConversationList() {
|
||||
return conversationList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.tencent.qcloud.tuikit.timcommon.R;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAction;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.action.PopMenuAdapter;
|
||||
import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Menu {
|
||||
private static final int SHADOW_WIDTH = 10;
|
||||
private static final int Y_OFFSET = 4;
|
||||
|
||||
private ListView mMenuList;
|
||||
private PopMenuAdapter mMenuAdapter;
|
||||
private PopupWindow mMenuWindow;
|
||||
private List<PopMenuAction> mActions = new ArrayList<>();
|
||||
private Activity mActivity;
|
||||
private View mAttachView;
|
||||
|
||||
public Menu(Activity activity, View attach) {
|
||||
mActivity = activity;
|
||||
mAttachView = attach;
|
||||
}
|
||||
|
||||
public void setMenuAction(List<PopMenuAction> menuActions) {
|
||||
mActions.clear();
|
||||
mActions.addAll(menuActions);
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
if (mMenuWindow == null) {
|
||||
return false;
|
||||
}
|
||||
return mMenuWindow.isShowing();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
mMenuWindow.dismiss();
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (mActions == null || mActions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
mMenuWindow = new PopupWindow(mActivity);
|
||||
mMenuWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mMenuWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mMenuWindow.setBackgroundDrawable(new ColorDrawable());
|
||||
|
||||
mMenuAdapter = new PopMenuAdapter();
|
||||
mMenuAdapter.setDataSource(mActions);
|
||||
View menuView = LayoutInflater.from(mActivity).inflate(R.layout.core_pop_menu, null);
|
||||
menuView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
mMenuWindow.setContentView(menuView);
|
||||
mMenuList = menuView.findViewById(R.id.menu_pop_list);
|
||||
mMenuList.setAdapter(mMenuAdapter);
|
||||
mMenuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
PopMenuAction action = (PopMenuAction) mMenuAdapter.getItem(position);
|
||||
if (action != null && action.getActionClickListener() != null) {
|
||||
action.getActionClickListener().onActionClick(position, mActions.get(position));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
int paddingLeftRight = ScreenUtil.dip2px(15.0f);
|
||||
int paddingTopBottom = ScreenUtil.dip2px(12.0f);
|
||||
|
||||
int itemWidth = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_width);
|
||||
int itemHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.core_pop_menu_item_height);
|
||||
mMenuWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
int[] location = new int[2];
|
||||
mAttachView.getLocationOnScreen(location);
|
||||
int rowCount = mActions.size();
|
||||
int indicatorHeight = mActivity.getResources().getDimensionPixelOffset(R.dimen.core_pop_menu_indicator_height);
|
||||
|
||||
int popWidth = itemWidth + paddingLeftRight * 2 - SHADOW_WIDTH;
|
||||
int popHeight = itemHeight * rowCount + paddingTopBottom * 2 - SHADOW_WIDTH;
|
||||
|
||||
float anchorWidth = mAttachView.getWidth();
|
||||
float indicatorX = anchorWidth / 2 + indicatorHeight;
|
||||
int screenWidth = ScreenUtil.getScreenWidth(mActivity);
|
||||
int x = location[0] - indicatorHeight;
|
||||
int y;
|
||||
float xOffset = anchorWidth / 2;
|
||||
// If it is on the right, the x-coordinate of the small arrow and the x-position of the pop-up window will change
|
||||
if (location[0] * 2 + anchorWidth > screenWidth) {
|
||||
indicatorX = popWidth - anchorWidth / 2 - xOffset;
|
||||
x = (int) (location[0] + anchorWidth - popWidth + xOffset);
|
||||
}
|
||||
float anchorHeight = mAttachView.getHeight();
|
||||
y = (int) (location[1] + anchorHeight) + Y_OFFSET;
|
||||
popHeight = popHeight - indicatorHeight;
|
||||
|
||||
Drawable backgroundDrawable = getBackgroundDrawable(popWidth, popHeight, indicatorX, indicatorHeight, 16);
|
||||
menuView.setBackground(backgroundDrawable);
|
||||
|
||||
mMenuWindow.setFocusable(true);
|
||||
mMenuWindow.setTouchable(true);
|
||||
mMenuWindow.setOutsideTouchable(true);
|
||||
mMenuWindow.showAtLocation(mAttachView, Gravity.NO_GRAVITY, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a popup background with small triangles
|
||||
*/
|
||||
public Drawable getBackgroundDrawable(final float widthPixel, final float heightPixel, float indicatorX, float indicatorHeight, float radius) {
|
||||
int borderWidth = SHADOW_WIDTH;
|
||||
|
||||
Path path = new Path();
|
||||
Drawable drawable = new Drawable() {
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setShadowLayer(borderWidth, 0, 0, 0xFFAAAAAA);
|
||||
path.addRoundRect(new RectF(borderWidth, indicatorHeight + borderWidth, widthPixel - borderWidth, heightPixel + indicatorHeight - borderWidth),
|
||||
radius, radius, Path.Direction.CW);
|
||||
path.moveTo(indicatorX - indicatorHeight, indicatorHeight + borderWidth);
|
||||
path.lineTo(indicatorX, borderWidth);
|
||||
path.lineTo(indicatorX + indicatorHeight, indicatorHeight + borderWidth);
|
||||
path.close();
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
};
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,543 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.tencent.imsdk.BaseConstants;
|
||||
import com.tencent.imsdk.v2.V2TIMCallback;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationOperationResult;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationResult;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupMemberFullInfo;
|
||||
import com.tencent.imsdk.v2.V2TIMGroupMemberInfoResult;
|
||||
import com.tencent.imsdk.v2.V2TIMManager;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUICallback;
|
||||
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter;
|
||||
import com.tencent.qcloud.tuicore.util.ToastUtil;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.BuildConfig;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationUserStatusBean;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.config.TUIConversationConfig;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversationProvider {
|
||||
private static final String TAG = ConversationProvider.class.getSimpleName();
|
||||
|
||||
protected boolean isFinished = false;
|
||||
protected long nextLoadSeq = 0L;
|
||||
|
||||
private List<ConversationInfo> markConversationInfoList = new ArrayList<>();
|
||||
private HashMap<String, V2TIMConversation> markUnreadMap = new HashMap<>();
|
||||
|
||||
public void loadConversation(long startSeq, int loadCount, final IUIKitCallback<List<ConversationInfo>> callBack) {
|
||||
TUIConversationLog.i(TAG, "loadConversation startSeq " + startSeq + " loadCount " + loadCount);
|
||||
|
||||
V2TIMManager.getConversationManager().getConversationList(startSeq, loadCount, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(
|
||||
TAG, "loadConversation getConversationList error, code = " + code + ", desc = " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> v2TIMConversationList = v2TIMConversationResult.getConversationList();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(v2TIMConversationList);
|
||||
TUIConversationLog.i(TAG,
|
||||
"loadConversation getConversationList success size " + conversationInfoList.size() + " nextSeq " + v2TIMConversationResult.getNextSeq()
|
||||
+ " isFinished " + v2TIMConversationResult.isFinished());
|
||||
if (!conversationInfoList.isEmpty()) {
|
||||
TUIConversationLog.i(TAG,
|
||||
"loadConversation getConversationList success first " + conversationInfoList.get(0) + " last "
|
||||
+ conversationInfoList.get(conversationInfoList.size() - 1));
|
||||
}
|
||||
isFinished = v2TIMConversationResult.isFinished();
|
||||
nextLoadSeq = v2TIMConversationResult.getNextSeq();
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, conversationInfoList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadMoreConversation(int loadCount, IUIKitCallback<List<ConversationInfo>> callBack) {
|
||||
if (isFinished) {
|
||||
return;
|
||||
}
|
||||
loadConversation(nextLoadSeq, loadCount, callBack);
|
||||
}
|
||||
|
||||
public boolean isLoadFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public void getConversation(String conversationID, IUIKitCallback<ConversationInfo> callback) {
|
||||
V2TIMManager.getConversationManager().getConversation(conversationID, new V2TIMValueCallback<V2TIMConversation>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversation v2TIMConversation) {
|
||||
ConversationInfo conversationInfo = ConversationUtils.convertV2TIMConversation(v2TIMConversation);
|
||||
TUIConversationUtils.callbackOnSuccess(callback, conversationInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.v(TAG, "getConversation error, code = " + code + ", desc = " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getTotalUnreadMessageCount(IUIKitCallback<Long> callBack) {
|
||||
V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback<Long>() {
|
||||
@Override
|
||||
public void onSuccess(Long count) {
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {}
|
||||
});
|
||||
}
|
||||
|
||||
public void setConversationTop(String conversationId, boolean isTop, IUIKitCallback<Void> callBack) {
|
||||
V2TIMManager.getConversationManager().pinConversation(conversationId, isTop, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationFold(String conversationID, boolean isFold, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
conversationIDList.add(conversationID);
|
||||
V2TIMManager.getConversationManager().markConversation(
|
||||
conversationIDList, V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD, isFold, new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationFold error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationHidden(String conversationID, boolean isHidden, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(conversationID)) {
|
||||
conversationIDList.add(conversationID);
|
||||
}
|
||||
V2TIMManager.getConversationManager().markConversation(conversationIDList, V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE, isHidden,
|
||||
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationHidden error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationRead(String conversationID, TUICallback callback) {
|
||||
V2TIMManager.getConversationManager().markConversation(Collections.singletonList(conversationID),
|
||||
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD, false, new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUICallback.onSuccess(callback);
|
||||
} else {
|
||||
TUICallback.onError(callback, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationRead error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUICallback.onError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void cleanConversationUnreadCount(String conversationID, TUICallback callback) {
|
||||
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUICallback.onSuccess(callback);
|
||||
TUIConversationLog.i(TAG, "cleanConversationUnreadCount success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUICallback.onError(callback, code, desc);
|
||||
TUIConversationLog.e(
|
||||
TAG, "cleanConversationUnreadCount error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationUnread(String conversationID, TUICallback callback) {
|
||||
V2TIMManager.getConversationManager().markConversation(Collections.singletonList(conversationID),
|
||||
V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD, true, new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUICallback.onSuccess(callback);
|
||||
} else {
|
||||
TUICallback.onError(callback, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUICallback.onError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread, IUIKitCallback<Void> callback) {
|
||||
List<String> conversationIDList = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
conversationIDList.add(conversationInfo.getConversationId());
|
||||
}
|
||||
if (!markUnread && conversationInfo.getUnRead() > 0) {
|
||||
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationInfo.getConversationId(), 0, 0, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "markConversationUnread->cleanConversationUnreadMessageCount success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(
|
||||
TAG, "cleanConversationUnreadMessageCount error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (markUnread != conversationInfo.isMarkUnread()) {
|
||||
V2TIMManager.getConversationManager().markConversation(conversationIDList, V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD, markUnread,
|
||||
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
if (v2TIMConversationOperationResults.size() == 0) {
|
||||
return;
|
||||
}
|
||||
V2TIMConversationOperationResult result = v2TIMConversationOperationResults.get(0);
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
} else {
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, result.getResultCode(), result.getResultInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, TAG, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteConversation(String conversationId, IUIKitCallback<Void> callBack) {
|
||||
V2TIMManager.getConversationManager().deleteConversation(conversationId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "deleteConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "deleteConversation success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearHistoryMessage(String userId, boolean isGroup, IUIKitCallback<Void> callBack) {
|
||||
if (isGroup) {
|
||||
V2TIMManager.getMessageManager().clearGroupHistoryMessage(userId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "clearConversationMessage error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "clearConversationMessage success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
V2TIMManager.getMessageManager().clearC2CHistoryMessage(userId, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "clearConversationMessage error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callBack, TAG, code, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "clearConversationMessage success");
|
||||
TUIConversationUtils.callbackOnSuccess(callBack, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void getGroupMemberIconList(String groupId, int iconCount, IUIKitCallback<List<Object>> callback) {
|
||||
V2TIMManager.getGroupManager().getGroupMemberList(
|
||||
groupId, V2TIMGroupMemberFullInfo.V2TIM_GROUP_MEMBER_FILTER_ALL, 0, new V2TIMValueCallback<V2TIMGroupMemberInfoResult>() {
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
TUIConversationLog.e("ConversationIconView",
|
||||
"getGroupMemberList failed! groupID:" + groupId + "|code:" + code + "|desc: " + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(V2TIMGroupMemberInfoResult v2TIMGroupMemberInfoResult) {
|
||||
List<V2TIMGroupMemberFullInfo> v2TIMGroupMemberFullInfoList = v2TIMGroupMemberInfoResult.getMemberInfoList();
|
||||
int faceSize = Math.min(v2TIMGroupMemberFullInfoList.size(), iconCount);
|
||||
final List<Object> urlList = new ArrayList<>();
|
||||
for (int i = 0; i < faceSize; i++) {
|
||||
V2TIMGroupMemberFullInfo v2TIMGroupMemberFullInfo = v2TIMGroupMemberFullInfoList.get(i);
|
||||
urlList.add(v2TIMGroupMemberFullInfo.getFaceUrl());
|
||||
}
|
||||
TUIConversationUtils.callbackOnSuccess(callback, urlList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadConversationUserStatus(List<ConversationInfo> dataSource, IUIKitCallback<Map<String, ConversationUserStatusBean>> callback) {
|
||||
if (dataSource == null || dataSource.size() == 0) {
|
||||
TUIConversationLog.d(TAG, "loadConversationUserStatus datasource is null");
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> userList = new ArrayList<>();
|
||||
for (ConversationInfo itemBean : dataSource) {
|
||||
if (itemBean.isGroup()) {
|
||||
continue;
|
||||
}
|
||||
userList.add(itemBean.getId());
|
||||
}
|
||||
if (userList.isEmpty()) {
|
||||
TUIConversationLog.d(TAG, "loadConversationUserStatus userList is empty");
|
||||
return;
|
||||
}
|
||||
V2TIMManager.getInstance().getUserStatus(userList, new V2TIMValueCallback<List<V2TIMUserStatus>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMUserStatus> v2TIMUserStatuses) {
|
||||
TUIConversationLog.i(TAG, "getUserStatus success");
|
||||
Map<String, ConversationUserStatusBean> userStatusBeanMap = new HashMap<>();
|
||||
for (V2TIMUserStatus item : v2TIMUserStatuses) {
|
||||
ConversationUserStatusBean conversationUserStatusBean = new ConversationUserStatusBean();
|
||||
conversationUserStatusBean.setV2TIMUserStatus(item);
|
||||
userStatusBeanMap.put(item.getUserID(), conversationUserStatusBean);
|
||||
}
|
||||
TUIConversationUtils.callbackOnSuccess(callback, userStatusBeanMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getUserStatus error code = " + code + ",des = " + desc);
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
if (code == TUIConstants.BuyingFeature.ERR_SDK_INTERFACE_NOT_SUPPORT && TUIConversationConfig.getInstance().isShowUserStatus()
|
||||
&& BuildConfig.DEBUG) {
|
||||
ToastUtil.toastLongMessage(desc);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void subscribeConversationUserStatus(List<String> userIdList, IUIKitCallback<Void> callback) {
|
||||
if (userIdList == null || userIdList.size() == 0) {
|
||||
TUIConversationLog.e(TAG, "subscribeConversationUserStatus userId is null");
|
||||
TUIConversationUtils.callbackOnError(callback, BaseConstants.ERR_INVALID_PARAMETERS, "userid list is null");
|
||||
return;
|
||||
}
|
||||
|
||||
V2TIMManager.getInstance().subscribeUserStatus(userIdList, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "subscribeConversationUserStatus error code = " + code + ",des = " + desc);
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getMarkConversationList(
|
||||
final V2TIMConversationListFilter filter, long nextSeq, int count, boolean fromStart, IUIKitCallback<List<ConversationInfo>> callback) {
|
||||
if (fromStart) {
|
||||
markConversationInfoList.clear();
|
||||
}
|
||||
V2TIMManager.getConversationManager().getConversationListByFilter(filter, nextSeq, count, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
|
||||
List<ConversationInfo> conversationInfoList = ConversationUtils.convertV2TIMConversationList(conversationList);
|
||||
markConversationInfoList.addAll(conversationInfoList);
|
||||
|
||||
if (!v2TIMConversationResult.isFinished()) {
|
||||
getMarkConversationList(filter, v2TIMConversationResult.getNextSeq(), count, false, callback);
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(markConversationInfoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getMarkConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearAllUnreadMessage(IUIKitCallback<Void> callback) {
|
||||
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount("", 0, 0, new V2TIMCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
TUIConversationLog.i(TAG, "clearAllUnreadMessage success");
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.i(TAG, "clearAllUnreadMessage error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
|
||||
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
|
||||
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD);
|
||||
getMarkUnreadConversationList(filter, 0, 100, true, new V2TIMValueCallback<HashMap<String, V2TIMConversation>>() {
|
||||
@Override
|
||||
public void onSuccess(HashMap<String, V2TIMConversation> stringV2TIMConversationHashMap) {
|
||||
if (stringV2TIMConversationHashMap.size() == 0) {
|
||||
return;
|
||||
}
|
||||
List<String> unreadConversationIDList = new ArrayList<>();
|
||||
Iterator<Map.Entry<String, V2TIMConversation>> iterator = markUnreadMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, V2TIMConversation> entry = iterator.next();
|
||||
unreadConversationIDList.add(entry.getKey());
|
||||
}
|
||||
|
||||
V2TIMManager.getConversationManager().markConversation(unreadConversationIDList, V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_UNREAD, false,
|
||||
new V2TIMValueCallback<List<V2TIMConversationOperationResult>>() {
|
||||
@Override
|
||||
public void onSuccess(List<V2TIMConversationOperationResult> v2TIMConversationOperationResults) {
|
||||
for (V2TIMConversationOperationResult result : v2TIMConversationOperationResults) {
|
||||
if (result.getResultCode() == BaseConstants.ERR_SUCC) {
|
||||
V2TIMConversation v2TIMConversation = markUnreadMap.get(result.getConversationID());
|
||||
if (!v2TIMConversation.getMarkList().contains(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_HIDE)) {
|
||||
markUnreadMap.remove(result.getConversationID());
|
||||
}
|
||||
}
|
||||
}
|
||||
TUIConversationUtils.callbackOnSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG,
|
||||
"triggerClearAllUnreadMessage->markConversation error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
TUIConversationUtils.callbackOnError(callback, code, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG,
|
||||
"triggerClearAllUnreadMessage->getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getMarkUnreadConversationList(
|
||||
V2TIMConversationListFilter filter, long nextSeq, int count, boolean fromStart, V2TIMValueCallback<HashMap<String, V2TIMConversation>> callback) {
|
||||
if (fromStart) {
|
||||
markUnreadMap.clear();
|
||||
}
|
||||
V2TIMManager.getConversationManager().getConversationListByFilter(filter, nextSeq, count, new V2TIMValueCallback<V2TIMConversationResult>() {
|
||||
@Override
|
||||
public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
|
||||
List<V2TIMConversation> conversationList = v2TIMConversationResult.getConversationList();
|
||||
for (V2TIMConversation conversation : conversationList) {
|
||||
markUnreadMap.put(conversation.getConversationID(), conversation);
|
||||
}
|
||||
|
||||
if (!v2TIMConversationResult.isFinished()) {
|
||||
getMarkUnreadConversationList(filter, v2TIMConversationResult.getNextSeq(), count, false, callback);
|
||||
} else {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(markUnreadMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code, String desc) {
|
||||
TUIConversationLog.e(TAG, "getMarkUnreadConversationList error:" + code + ", desc:" + ErrorMessageConverter.convertIMError(code, desc));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,506 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.presenter;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.tencent.imsdk.v2.V2TIMConversation;
|
||||
import com.tencent.imsdk.v2.V2TIMConversationListFilter;
|
||||
import com.tencent.imsdk.v2.V2TIMMessage;
|
||||
import com.tencent.imsdk.v2.V2TIMUserStatus;
|
||||
import com.tencent.qcloud.tuicore.TUIConstants;
|
||||
import com.tencent.qcloud.tuicore.TUICore;
|
||||
import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.TUIConversationService;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.ConversationUtils;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.commonutil.TUIConversationLog;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.ConversationEventListener;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.interfaces.IConversationListAdapter;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.model.ConversationProvider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversationFoldPresenter {
|
||||
private static final String TAG = ConversationFoldPresenter.class.getSimpleName();
|
||||
|
||||
private static final int GET_CONVERSATION_COUNT = 100;
|
||||
|
||||
ConversationEventListener conversationEventForMarkObserver;
|
||||
|
||||
private final ConversationProvider provider;
|
||||
|
||||
private IConversationListAdapter adapter;
|
||||
|
||||
private final List<ConversationInfo> loadedConversationInfoList = new ArrayList<>();
|
||||
|
||||
public ConversationFoldPresenter() {
|
||||
provider = new ConversationProvider();
|
||||
}
|
||||
|
||||
public void setAdapter(IConversationListAdapter adapter) {
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
public void initListener() {
|
||||
conversationEventForMarkObserver = new ConversationEventListener() {
|
||||
@Override
|
||||
public void deleteConversation(String chatId, boolean isGroup) {
|
||||
ConversationFoldPresenter.this.deleteConversationFromUI(chatId, isGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearConversationMessage(String chatId, boolean isGroup) {}
|
||||
|
||||
@Override
|
||||
public void clearFoldMarkAndDeleteConversation(String conversationId) {
|
||||
ConversationFoldPresenter.this.deleteConversationFromUI(conversationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConversationTop(String chatId, boolean isChecked, IUIKitCallback<Void> iuiKitCallBack) {}
|
||||
|
||||
@Override
|
||||
public boolean isTopConversation(String chatId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUnreadTotal() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncServerFinish() {}
|
||||
|
||||
@Override
|
||||
public void updateTotalUnreadMessageCount(long count) {}
|
||||
|
||||
@Override
|
||||
public void onNewConversation(List<ConversationInfo> conversationList) {
|
||||
ConversationFoldPresenter.this.onNewConversation(conversationList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationChanged(List<ConversationInfo> conversationList) {
|
||||
ConversationFoldPresenter.this.onConversationChanged(conversationList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFriendRemarkChanged(String id, String remark) {}
|
||||
|
||||
@Override
|
||||
public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {}
|
||||
|
||||
@Override
|
||||
public void refreshUserStatusFragmentUI() {}
|
||||
|
||||
@Override
|
||||
public void onReceiveMessage(String conversationID, boolean isTypingMessage) {
|
||||
processNewMessage(conversationID, isTypingMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSendForHideConversation(String conversationID) {}
|
||||
|
||||
@Override
|
||||
public void onConversationDeleted(List<String> conversationIDList) {
|
||||
ConversationFoldPresenter.this.onConversationDeleted(conversationIDList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConversationLastMessageBeanChanged(String conversationID, TUIMessageBean messageBean) {
|
||||
ConversationFoldPresenter.this.onConversationLastMessageBeanChanged(conversationID, messageBean);
|
||||
}
|
||||
};
|
||||
TUIConversationService.getInstance().addConversationEventListener(conversationEventForMarkObserver);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
TUIConversationService.getInstance().removeConversationEventListener(conversationEventForMarkObserver);
|
||||
this.conversationEventForMarkObserver = null;
|
||||
}
|
||||
|
||||
public void loadConversation() {
|
||||
TUIConversationLog.i(TAG, "loadConversation");
|
||||
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
|
||||
long markType = V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_FOLD;
|
||||
filter.setMarkType(markType);
|
||||
provider.getMarkConversationList(filter, 0, GET_CONVERSATION_COUNT, true, new IUIKitCallback<List<ConversationInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(List<ConversationInfo> conversationInfoList) {
|
||||
if (conversationInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collections.sort(conversationInfoList);
|
||||
List<ConversationInfo> loadList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : conversationInfoList) {
|
||||
if (!conversationInfo.isMarkHidden()) {
|
||||
loadList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
onLoadConversationCompleted(loadList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(TAG, "loadConversation error:" + errCode + ", " + errMsg);
|
||||
if (adapter != null) {
|
||||
adapter.onLoadingStateChanged(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onLoadConversationCompleted(List<ConversationInfo> conversationInfoList) {
|
||||
onNewConversation(conversationInfoList);
|
||||
if (adapter != null) {
|
||||
adapter.onLoadingStateChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void onNewConversation(List<ConversationInfo> conversationInfoList) {
|
||||
TUIConversationLog.i(TAG, "onNewConversation conversations:" + conversationInfoList);
|
||||
|
||||
if (conversationInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
getLastMessageBean(conversationInfoList);
|
||||
|
||||
ArrayList<ConversationInfo> processedInfoList = processFoldedAndHiddenConversation(conversationInfoList);
|
||||
|
||||
List<ConversationInfo> exists = new ArrayList<>();
|
||||
Iterator<ConversationInfo> iterator = processedInfoList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConversationInfo update = iterator.next();
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo cacheInfo = loadedConversationInfoList.get(i);
|
||||
|
||||
if (cacheInfo.getConversationId().equals(update.getConversationId())) {
|
||||
loadedConversationInfoList.set(i, update);
|
||||
iterator.remove();
|
||||
exists.add(update);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(processedInfoList);
|
||||
loadedConversationInfoList.addAll(processedInfoList);
|
||||
if (adapter != null) {
|
||||
Collections.sort(loadedConversationInfoList);
|
||||
adapter.onDataSourceChanged(loadedConversationInfoList);
|
||||
for (ConversationInfo info : processedInfoList) {
|
||||
int index = loadedConversationInfoList.indexOf(info);
|
||||
if (index != -1) {
|
||||
adapter.onItemInserted(index);
|
||||
}
|
||||
}
|
||||
|
||||
for (ConversationInfo info : exists) {
|
||||
int index = loadedConversationInfoList.indexOf(info);
|
||||
if (index != -1) {
|
||||
adapter.onItemChanged(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onConversationChanged(List<ConversationInfo> conversationInfoList) {
|
||||
TUIConversationLog.i(TAG, "onConversationChanged conversations:" + conversationInfoList);
|
||||
getLastMessageBean(conversationInfoList);
|
||||
ArrayList<ConversationInfo> addInfoList = new ArrayList<>();
|
||||
ArrayList<ConversationInfo> infoList = processFoldedAndHiddenConversation(conversationInfoList);
|
||||
|
||||
ArrayList<ConversationInfo> changedInfoList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : infoList) {
|
||||
if (!ConversationUtils.isIgnored(conversationInfo)) {
|
||||
boolean exists = false;
|
||||
for (ConversationInfo loadedInfo : loadedConversationInfoList) {
|
||||
if (TextUtils.equals(conversationInfo.getConversationId(), loadedInfo.getConversationId())) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exists) {
|
||||
TUIConversationLog.i(TAG, "onConversationChanged conversationInfo " + conversationInfo);
|
||||
changedInfoList.add(conversationInfo);
|
||||
} else {
|
||||
addInfoList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!addInfoList.isEmpty()) {
|
||||
onNewConversation(addInfoList);
|
||||
}
|
||||
|
||||
if (changedInfoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
refreshChangedInfo(loadedConversationInfoList, changedInfoList);
|
||||
}
|
||||
|
||||
private void refreshChangedInfo(List<ConversationInfo> uiSourceInfoList, List<ConversationInfo> changedInfoList) {
|
||||
Collections.sort(changedInfoList);
|
||||
|
||||
HashMap<ConversationInfo, Integer> indexMap = new HashMap<>();
|
||||
for (int j = 0; j < changedInfoList.size(); j++) {
|
||||
ConversationInfo update = changedInfoList.get(j);
|
||||
for (int i = 0; i < uiSourceInfoList.size(); i++) {
|
||||
ConversationInfo cacheInfo = uiSourceInfoList.get(i);
|
||||
|
||||
if (cacheInfo.getConversationId().equals(update.getConversationId())) {
|
||||
if (update.getStatusType() == V2TIMUserStatus.V2TIM_USER_STATUS_UNKNOWN) {
|
||||
update.setStatusType(cacheInfo.getStatusType());
|
||||
}
|
||||
uiSourceInfoList.set(i, update);
|
||||
indexMap.put(update, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adapter != null) {
|
||||
Collections.sort(uiSourceInfoList);
|
||||
adapter.onDataSourceChanged(uiSourceInfoList);
|
||||
int minRefreshIndex = Integer.MAX_VALUE;
|
||||
int maxRefreshIndex = Integer.MIN_VALUE;
|
||||
for (ConversationInfo info : changedInfoList) {
|
||||
Integer oldIndexObj = indexMap.get(info);
|
||||
if (oldIndexObj == null) {
|
||||
continue;
|
||||
}
|
||||
int oldIndex = oldIndexObj;
|
||||
int newIndex = uiSourceInfoList.indexOf(info);
|
||||
if (newIndex != -1) {
|
||||
minRefreshIndex = Math.min(minRefreshIndex, Math.min(oldIndex, newIndex));
|
||||
maxRefreshIndex = Math.max(maxRefreshIndex, Math.max(oldIndex, newIndex));
|
||||
}
|
||||
}
|
||||
int count;
|
||||
if (minRefreshIndex == maxRefreshIndex) {
|
||||
count = 1;
|
||||
} else {
|
||||
count = maxRefreshIndex - minRefreshIndex + 1;
|
||||
}
|
||||
if (count > 0 && maxRefreshIndex >= minRefreshIndex) {
|
||||
adapter.onItemRangeChanged(minRefreshIndex, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<ConversationInfo> processFoldedAndHiddenConversation(List<ConversationInfo> infoList) {
|
||||
ArrayList<ConversationInfo> changedInfoList = new ArrayList<>();
|
||||
for (ConversationInfo conversationInfo : infoList) {
|
||||
int uiIndex = -1;
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo loadedInfo = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(conversationInfo.getConversationId(), loadedInfo.getConversationId())) {
|
||||
uiIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uiIndex >= 0) {
|
||||
if (!conversationInfo.isMarkFold() || conversationInfo.isMarkHidden()) {
|
||||
loadedConversationInfoList.remove(uiIndex);
|
||||
if (adapter != null) {
|
||||
adapter.onItemRemoved(uiIndex);
|
||||
}
|
||||
} else if (conversationInfo.isMarkFold()) {
|
||||
changedInfoList.add(conversationInfo);
|
||||
}
|
||||
} else {
|
||||
if (conversationInfo.isMarkFold() && !conversationInfo.isMarkHidden()) {
|
||||
changedInfoList.add(conversationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changedInfoList;
|
||||
}
|
||||
|
||||
private void processNewMessage(String conversationID, boolean isTypingMessage) {
|
||||
if (TextUtils.isEmpty(conversationID)) {
|
||||
return;
|
||||
}
|
||||
if (isTypingMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConversationInfo cacheInfo = null;
|
||||
for (ConversationInfo conversationInfo : loadedConversationInfoList) {
|
||||
if (TextUtils.equals(conversationID, conversationInfo.getConversationId())) {
|
||||
cacheInfo = conversationInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheInfo != null) {
|
||||
if (cacheInfo.isMarkUnread()) {
|
||||
markConversationUnread(cacheInfo, false);
|
||||
}
|
||||
} else {
|
||||
provider.getConversation(conversationID, new IUIKitCallback<ConversationInfo>() {
|
||||
@Override
|
||||
public void onSuccess(ConversationInfo conversationInfo) {
|
||||
if (conversationInfo.isMarkHidden()) {
|
||||
markConversationHidden(conversationInfo, false);
|
||||
}
|
||||
if (conversationInfo.isMarkUnread()) {
|
||||
markConversationUnread(conversationInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteConversation(ConversationInfo conversation) {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIConversation.CONVERSATION_ID, conversation.getConversationId());
|
||||
TUICore.callService(TUIConstants.TUIConversation.SERVICE_NAME, TUIConstants.TUIConversation.METHOD_DELETE_CONVERSATION, param);
|
||||
}
|
||||
|
||||
public void markConversationHidden(ConversationInfo conversationInfo, boolean isHidden) {
|
||||
if (conversationInfo == null || TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
TUIConversationLog.e(TAG, "markConversationHidden error: invalid conversationInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
provider.markConversationHidden(conversationInfo.getConversationId(), isHidden, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {
|
||||
conversationInfo.setMarkHidden(isHidden);
|
||||
TUIConversationLog.i(TAG, "markConversationHidden success, conversationID:" + conversationInfo.getConversationId() + ", isHidden:" + isHidden);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(
|
||||
TAG, "markConversationHidden error, conversationID:" + conversationInfo.getConversationId() + ", code:" + errCode + "|msg:" + errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void markConversationUnread(ConversationInfo conversationInfo, boolean markUnread) {
|
||||
if (conversationInfo == null || TextUtils.isEmpty(conversationInfo.getConversationId())) {
|
||||
TUIConversationLog.e(TAG, "markConversationUnread error: invalid conversationInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
provider.markConversationUnread(conversationInfo, markUnread, new IUIKitCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void data) {
|
||||
conversationInfo.setMarkUnread(markUnread);
|
||||
TUIConversationLog.i(TAG, "markConversationRead success, conversationID:" + conversationInfo.getConversationId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String module, int errCode, String errMsg) {
|
||||
TUIConversationLog.e(
|
||||
TAG, "markConversationRead error, conversationID:" + conversationInfo.getConversationId() + ", code:" + errCode + "|msg:" + errMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteConversationFromUI(String id, boolean isGroup) {
|
||||
if (!isGroup) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo info = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(info.getId(), id)) {
|
||||
boolean isRemove = loadedConversationInfoList.remove(info);
|
||||
if (adapter != null && isRemove) {
|
||||
adapter.onItemRemoved(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteConversationFromUI(String conversationId) {
|
||||
if (TextUtils.isEmpty(conversationId)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < loadedConversationInfoList.size(); i++) {
|
||||
ConversationInfo info = loadedConversationInfoList.get(i);
|
||||
if (TextUtils.equals(info.getConversationId(), conversationId)) {
|
||||
boolean isRemove = loadedConversationInfoList.remove(info);
|
||||
if (adapter != null && isRemove) {
|
||||
adapter.onItemRemoved(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onConversationDeleted(List<String> conversationIdList) {
|
||||
if (conversationIdList == null || conversationIdList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String conversationId : conversationIdList) {
|
||||
deleteConversationFromUI(conversationId);
|
||||
}
|
||||
}
|
||||
|
||||
private void getLastMessageBean(List<ConversationInfo> conversationInfoList) {
|
||||
if (conversationInfoList == null || conversationInfoList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, TUIMessageBean> messageBeanMap = new HashMap<>();
|
||||
for (ConversationInfo conversationInfo : conversationInfoList) {
|
||||
if (conversationInfo.getLastMessage() != null && conversationInfo.getLastTUIMessageBean() == null) {
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIChat.Method.GetTUIMessageBean.V2TIM_MESSAGE, conversationInfo.getLastMessage());
|
||||
Object messageBeanObj = TUICore.callService(
|
||||
TUIConstants.TUIChat.SERVICE_NAME, TUIConstants.TUIChat.Method.GetTUIMessageBean.METHOD_NAME, param);
|
||||
if (messageBeanObj instanceof TUIMessageBean) {
|
||||
TUIMessageBean messageBean = (TUIMessageBean) messageBeanObj;
|
||||
if (messageBean.needAsyncGetDisplayString()) {
|
||||
messageBeanMap.put(conversationInfo.getConversationId(), messageBean);
|
||||
continue;
|
||||
}
|
||||
conversationInfo.setLastTUIMessageBean(messageBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<String, Object> param = new HashMap<>();
|
||||
param.put(TUIConstants.TUIChat.Method.GetMessagesDisplayString.MESSAGE_MAP, messageBeanMap);
|
||||
TUICore.callService(TUIConstants.TUIChat.SERVICE_NAME, TUIConstants.TUIChat.Method.GetMessagesDisplayString.METHOD_NAME, param);
|
||||
}
|
||||
|
||||
private void onConversationLastMessageBeanChanged(String conversationID, TUIMessageBean messageBean) {
|
||||
ConversationInfo changedInfo = null;
|
||||
for (ConversationInfo conversationInfo : loadedConversationInfoList) {
|
||||
if (TextUtils.equals(conversationInfo.getConversationId(), conversationID)) {
|
||||
if (conversationInfo.getLastMessage() != null) {
|
||||
String msgID = conversationInfo.getLastMessage().getMsgID();
|
||||
if (TextUtils.equals(msgID, messageBean.getId())) {
|
||||
conversationInfo.setLastTUIMessageBean(messageBean);
|
||||
changedInfo = conversationInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changedInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ConversationInfo> changedInfoList = new ArrayList<>();
|
||||
changedInfoList.add(changedInfo);
|
||||
if (adapter != null) {
|
||||
adapter.onConversationChanged(changedInfoList);
|
||||
}
|
||||
refreshChangedInfo(loadedConversationInfoList, changedInfoList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tencent.qcloud.tuikit.tuiconversation.presenter;
|
||||
|
||||
import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback;
|
||||
import com.tencent.qcloud.tuikit.tuiconversation.model.ConversationProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConversationIconPresenter {
|
||||
private final ConversationProvider provider;
|
||||
|
||||
public ConversationIconPresenter() {
|
||||
provider = new ConversationProvider();
|
||||
}
|
||||
|
||||
public void getGroupMemberIconList(String groupId, IUIKitCallback<List<Object>> callback) {
|
||||
provider.getGroupMemberIconList(groupId, 9, callback);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="conversation_tab_selected_light">#147AFF</color>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="TUIConversationLightTheme" parent="TUIBaseLightTheme">
|
||||
<item name="conversation_tab_selected">@color/conversation_tab_selected_light</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="conversation_tab_selected_lively">#FF3B30</color>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="TUIConversationLivelyTheme" parent="TUIBaseLivelyTheme">
|
||||
<item name="conversation_tab_selected">@color/conversation_tab_selected_lively</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFFFF" />
|
||||
<corners android:radius="20dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
|
||||
</shape>
|
||||
|
After Width: | Height: | Size: 914 B |
|
After Width: | Height: | Size: 698 B |
|
After Width: | Height: | Size: 344 B |
|
After Width: | Height: | Size: 273 B |
|
After Width: | Height: | Size: 784 B |
|
After Width: | Height: | Size: 418 B |
|
After Width: | Height: | Size: 392 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="#1F767680"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
|
After Width: | Height: | Size: 644 B |
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/item_left"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingStart="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forward_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/black"
|
||||
android:text="@string/forward_list_label"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/white" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,64 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/bottom_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/conversation_bottom_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/divide_line"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/dialog_line_bg" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/conversation_bottom_bg"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingStart="38.4dp"
|
||||
android:paddingEnd="38.4dp"
|
||||
android:layout_marginTop="1.36dp"
|
||||
android:layout_marginBottom="46.08dp"
|
||||
android:orientation="horizontal" >
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:text="@string/not_display"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mark_read"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/mark_read"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/delete_chat"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="5.76dp"
|
||||
android:text="@string/chat_delete"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/timcommon_transparent"
|
||||
android:gravity="center_vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:gravity="center_vertical"
|
||||
android:background="@color/timcommon_transparent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationIconView
|
||||
android:id="@+id/conversation_icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
tools:background="@android:drawable/ic_menu_gallery"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/user_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_alignBottom="@id/conversation_icon"
|
||||
android:layout_alignEnd="@id/conversation_icon"
|
||||
android:visibility="visible"
|
||||
android:background="@drawable/conversation_minimalist_online_icon" />
|
||||
|
||||
<com.tencent.qcloud.tuikit.timcommon.component.UnreadCountTextView
|
||||
android:id="@+id/conversation_not_disturb_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_alignTop="@id/conversation_icon"
|
||||
android:layout_alignEnd="@id/conversation_icon"
|
||||
android:layout_marginEnd="-8dp"
|
||||
android:layout_marginTop="-8dp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="11sp"
|
||||
app:paint_color="#FF584C"
|
||||
tools:text=""
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/timcommon_transparent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="180dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="top|start"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/black_font_color"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
tools:text="Daniel"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fold_group_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:textSize="12sp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FF666666"
|
||||
tools:text="FoldGroup"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fold_group_name_divider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/fold_group_name"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#FF666666"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text=":"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_risk"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/conversation_list_text_margin_bottom"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/fold_group_name_divider"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/read_dot_bg"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="@string/conversation_risk_message_extra"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_at_all"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/conversation_risk"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/read_dot_bg"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="@string/ui_at_all"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_at_me"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/conversation_at_all"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/read_dot_bg"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="@string/ui_at_me"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_draft"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/conversation_at_me"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/read_dot_bg"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="@string/drafts"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_last_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:layout_gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_toEndOf="@id/conversation_draft"
|
||||
android:layout_toStartOf="@id/message_status_layout"
|
||||
android:layout_marginEnd="29dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FF666666"
|
||||
android:textSize="12sp"
|
||||
tools:text="Hello" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/message_status_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toStartOf="@id/conversation_time"
|
||||
android:layout_alignBottom="@id/conversation_time"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="2dp"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/message_status_sending"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@drawable/conversation_ic_sending_status"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/message_status_failed"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/conversation_ic_send_failed"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/conversation_title"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:textColor="#FF666666"
|
||||
android:textSize="12sp"
|
||||
android:lineHeight="14.32sp"
|
||||
tools:text="12:00"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/not_disturb"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:includeFontPadding="false"
|
||||
android:background="@drawable/conversation_minimalist_not_disturb_icon"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<com.tencent.qcloud.tuikit.timcommon.component.UnreadCountTextView
|
||||
android:id="@+id/conversation_unread"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/conversation_time"
|
||||
android:layout_marginStart="8dp"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="11sp"
|
||||
app:paint_color="#FF584C"
|
||||
android:layout_alignParentEnd="true"
|
||||
tools:text="2"
|
||||
tools:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_page_bg">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationLayout
|
||||
android:id="@+id/folded_conversation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,16 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.tencent.qcloud.tuikit.timcommon.component.MinimalistTitleBar
|
||||
android:id="@+id/conversation_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.FoldedConversationListLayout
|
||||
android:id="@+id/folded_conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/btn_margin_bottom"
|
||||
android:clickable="true">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationIconView
|
||||
android:id="@+id/conversation_user_icon_view"
|
||||
android:layout_width="41dp"
|
||||
android:layout_height="41dp"
|
||||
app:default_image="?attr/core_default_user_icon"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ForwardSelectLayout
|
||||
android:id="@+id/forward_conversation_layout"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/forward_list_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:cardElevation="16dp"
|
||||
app:contentPaddingBottom="40dp"
|
||||
app:contentPaddingLeft="16dp"
|
||||
app:contentPaddingRight="16dp"
|
||||
app:contentPaddingTop="14dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/forward_select_list_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/conversation_name_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/black"/>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btn_msg_ok"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/conversation_forward"
|
||||
android:textColor="#0365F9"
|
||||
android:textSize="14sp"
|
||||
android:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,58 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#99000000"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="40dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/conversation_forward_selected_page_border"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="22dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.33"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="#0365F9"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.33"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_weight="0.33" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout
|
||||
android:id="@+id/conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:lineHeight="41dp"
|
||||
android:text="@string/conversation_minimalist_chat"
|
||||
android:textColor="@color/black_font_color"
|
||||
android:textSize="34sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/home_rtcube"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="?attr/core_title_bar_back_icon"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:clickable="false" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:textColor="@color/font_blue"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/conversation_title_edit"
|
||||
android:layout_toStartOf="@+id/create_new_button" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/create_new_button"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="25dp"
|
||||
android:background="@drawable/conversation_minimalist_edit_icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/edit_done"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/conversation_minimalist_done"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:textColor="@color/font_blue"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_rtcube"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:lineHeight="41dp"
|
||||
android:visibility="gone"
|
||||
android:text="@string/conversation_minimalist_chat"
|
||||
android:textColor="@color/black_font_color"
|
||||
android:textSize="34sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,37 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/more_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="34dp"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.95"
|
||||
android:background="@drawable/common_dialog_react_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_below="@+id/layout_actions"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@drawable/common_dialog_react_bg"
|
||||
android:gravity="center"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="#147AFF"
|
||||
android:textSize="17sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout 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:id="@+id/swipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="#FFFFFF"
|
||||
app:clickToClose="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/bottom_wrapper_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:tag="Bottom4">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/more_view"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:background="@color/black"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/more_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/conversation_minimalist_more_icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/more_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/more_image"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/more_text"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mark_read"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toEndOf="@id/more_view"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mark_read_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mark_read_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/mark_read_image"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/mark_read"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center"
|
||||
android:layout_toEndOf="@id/mark_read"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/not_display"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/item_left"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="#FFFFFF"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="42dp">
|
||||
|
||||
<include
|
||||
layout="@layout/minimalist_conversation_list_item_sub_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:tag="Hover" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/select_checkbox"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@drawable/conversation_checkbox_selector"
|
||||
android:button="@null"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</LinearLayout>
|
||||
</com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_page_bg">
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationLayout
|
||||
android:id="@+id/conversation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<include layout="@layout/minimalist_bottom_bar"
|
||||
android:layout_marginBottom="@dimen/page_margin"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,46 @@
|
||||
<LinearLayout 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"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
layout="@layout/minimalist_header_view_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:background="@color/transparent"
|
||||
app:elevation="0dp"
|
||||
app:layout_insetEdge="none"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/search_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:visibility="gone"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.tencent.qcloud.tuikit.tuiconversation.minimalistui.widget.ConversationListLayout
|
||||
android:id="@+id/conversation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout 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:id="@+id/swipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
app:clickToClose="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/bottom_wrapper_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:tag="Bottom4">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/more_view"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:background="@color/black"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/more_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/conversation_minimalist_more_icon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/more_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/more_image"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:autoSizeMinTextSize="8sp"
|
||||
android:autoSizeMaxTextSize="12sp"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:text="@string/more_text"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mark_read"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toEndOf="@id/more_view"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mark_read_image"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mark_read_text"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/mark_read_image"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:autoSizeMinTextSize="8sp"
|
||||
android:autoSizeMaxTextSize="12sp"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:text="@string/mark_read"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/not_display"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/conversation_mark_swipe_bg"
|
||||
android:gravity="center"
|
||||
android:layout_toEndOf="@id/mark_read"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/not_display"
|
||||
android:textColor="@color/white"
|
||||
android:autoSizeMinTextSize="8sp"
|
||||
android:autoSizeMaxTextSize="12sp"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/item_left"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="@color/timcommon_transparent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/select_checkbox"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="6.23dp"
|
||||
android:background="@drawable/conversation_checkbox_selector"
|
||||
android:button="@null"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<include
|
||||
layout="@layout/minimalist_conversation_list_item_sub_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:tag="Hover" />
|
||||
|
||||
</LinearLayout>
|
||||
</com.tencent.qcloud.tuikit.timcommon.component.swipe.SwipeLayout>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="conversation_minimalist_chat">الدردشة</string>
|
||||
<string name="conversation_minimalist_chat_disconnected">فصل</string>
|
||||
<string name="conversation_minimalist_chat_connecting">ربط...</string>
|
||||
<string name="conversation_minimalist_chat_loading">جمع...</string>
|
||||
<string name="conversation_minimalist_search">البحث</string>
|
||||
<string name="conversation_minimalist_done">تم</string>
|
||||
<string name="has_all_read">تمت القراءة بالكامل</string>
|
||||
<string name="start_conversation">بدء محادثة</string>
|
||||
<string name="create_group_chat">إنشاء محادثة جماعية</string>
|
||||
<string name="more_text">المزيد</string>
|
||||
<string name="clear_message">مسح سجل المحادثة</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="conversation_minimalist_chat">聊天</string>
|
||||
<string name="conversation_minimalist_chat_disconnected">聊天(未連接)</string>
|
||||
<string name="conversation_minimalist_chat_connecting">連接中...</string>
|
||||
<string name="conversation_minimalist_chat_loading">收取中...</string>
|
||||
<string name="conversation_minimalist_search">搜索</string>
|
||||
<string name="conversation_minimalist_done">完成</string>
|
||||
<string name="has_all_read">全部已讀</string>
|
||||
<string name="start_conversation">發起會話</string>
|
||||
<string name="create_group_chat">創建群聊</string>
|
||||
<string name="more_text">更多</string>
|
||||
<string name="clear_message">清除聊天記錄</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="conversation_minimalist_chat">聊天</string>
|
||||
<string name="conversation_minimalist_chat_disconnected">聊天(未连接)</string>
|
||||
<string name="conversation_minimalist_chat_connecting">连接中...</string>
|
||||
<string name="conversation_minimalist_chat_loading">收取中...</string>
|
||||
<string name="conversation_minimalist_search">搜索</string>
|
||||
<string name="conversation_minimalist_done">完成</string>
|
||||
<string name="has_all_read">全部已读</string>
|
||||
<string name="start_conversation">发起会话</string>
|
||||
<string name="create_group_chat">创建群聊</string>
|
||||
<string name="more_text">更多</string>
|
||||
<string name="clear_message">清除聊天记录</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="MinimalistHeaderView">
|
||||
<attr name="header_title" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="conversation_delete_swipe_bg">#F24D4C</color>
|
||||
<color name="conversation_mark_swipe_bg">#147AFF</color>
|
||||
<color name="conversation_mark_swipe_dark_bg">#666666</color>
|
||||
<color name="conversation_hide_swipe_bg">#F29340</color>
|
||||
<color name="conversation_bottom_bg">#F9F9F9</color>
|
||||
|
||||
</resources>
|
||||