私聊改造:输入体验优化
This commit is contained in:
@@ -676,7 +676,6 @@
|
||||
android:label="单聊界面"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||
<activity
|
||||
android:name=".ui.im.avtivity.AddBlackListActivity"
|
||||
@@ -952,10 +951,12 @@
|
||||
<!-- 房间内私聊 -->
|
||||
<activity
|
||||
android:name=".room_chat.activity.NimRoomP2PMessageActivity"
|
||||
android:theme="@style/room_message_activity" />
|
||||
android:theme="@style/room_message_activity"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||
<activity
|
||||
android:name=".room_chat.activity.RoomMsgActivity"
|
||||
android:theme="@style/room_message_activity" />
|
||||
android:theme="@style/room_message_activity"
|
||||
android:windowSoftInputMode="stateHidden|adjustNothing" />
|
||||
<activity
|
||||
android:name=".room_chat.activity.RoomNewbieActivity"
|
||||
android:theme="@style/room_message_activity" />
|
||||
|
@@ -0,0 +1,44 @@
|
||||
package com.mango.moshen.ui.im;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.effective.android.panel.PanelSwitchHelper;
|
||||
|
||||
public class AutoHidePanelRecyclerView extends RecyclerView {
|
||||
|
||||
PanelSwitchHelper panelSwitchHelper;
|
||||
|
||||
public void setPanelSwitchHelper(PanelSwitchHelper panelSwitchHelper) {
|
||||
this.panelSwitchHelper = panelSwitchHelper;
|
||||
}
|
||||
|
||||
public AutoHidePanelRecyclerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
|
||||
public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setLayoutManager(new LinearLayoutManager(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
if (e != null && e.getAction() != MotionEvent.ACTION_CANCEL) {
|
||||
if (panelSwitchHelper != null) {
|
||||
panelSwitchHelper.hookSystemBackByPanelSwitcher();
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(e);
|
||||
}
|
||||
}
|
@@ -7,7 +7,9 @@ import com.netease.nim.uikit.api.model.contact.ContactEventListener;
|
||||
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
||||
import com.netease.nim.uikit.api.model.session.SessionEventListener;
|
||||
import com.netease.nim.uikit.business.session.actions.BaseAction;
|
||||
import com.netease.nim.uikit.business.session.actions.CameraAction;
|
||||
import com.netease.nim.uikit.business.session.actions.ImageAction;
|
||||
import com.netease.nim.uikit.business.session.actions.PhotoAction;
|
||||
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||
import com.mango.moshen.community.holder.DynamicSysHolder;
|
||||
import com.mango.moshen.community.im.WorldDynamicShareViewHolder;
|
||||
@@ -116,10 +118,11 @@ public class ImInitHelper {
|
||||
private void initP2PSessionCustomization() {
|
||||
SessionCustomization sessionCustomization = new SessionCustomization();
|
||||
ArrayList<BaseAction> actions = new ArrayList<>();
|
||||
actions.add(new ImageAction());
|
||||
actions.add(new PhotoAction());
|
||||
actions.add(new CameraAction());
|
||||
actions.add(new GiftAction());
|
||||
sessionCustomization.actions = actions;
|
||||
sessionCustomization.withSticker = true;
|
||||
sessionCustomization.withSticker = false;
|
||||
NimUIKit.setCommonP2PSessionCustomization(sessionCustomization);
|
||||
|
||||
// 语音派对
|
||||
|
878
app/src/main/java/com/mango/moshen/ui/im/InputPanel.java
Normal file
878
app/src/main/java/com/mango/moshen/ui/im/InputPanel.java
Normal file
@@ -0,0 +1,878 @@
|
||||
package com.mango.moshen.ui.im;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.Chronometer;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.effective.android.panel.PanelSwitchHelper;
|
||||
import com.effective.android.panel.interfaces.PanelHeightMeasurer;
|
||||
import com.effective.android.panel.interfaces.listener.OnPanelChangeListener;
|
||||
import com.effective.android.panel.view.panel.IPanelView;
|
||||
import com.effective.android.panel.view.panel.PanelView;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.ui.im.actions.GiftAction;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.mango.xchat_android_library.utils.SizeUtils;
|
||||
import com.netease.nim.uikit.api.NimUIKit;
|
||||
import com.netease.nim.uikit.api.UIKitOptions;
|
||||
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
||||
import com.netease.nim.uikit.business.ait.AitTextChangeListener;
|
||||
import com.netease.nim.uikit.business.session.actions.BaseAction;
|
||||
import com.netease.nim.uikit.business.session.actions.CameraAction;
|
||||
import com.netease.nim.uikit.business.session.actions.PhotoAction;
|
||||
import com.netease.nim.uikit.business.session.emoji.EmoticonPickerView;
|
||||
import com.netease.nim.uikit.business.session.emoji.IEmoticonSelectedListener;
|
||||
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
|
||||
import com.netease.nim.uikit.business.session.event.ActiveEvent;
|
||||
import com.netease.nim.uikit.business.session.module.Container;
|
||||
import com.netease.nim.uikit.business.session.module.input.ActionsPanel;
|
||||
import com.netease.nim.uikit.business.session.module.input.NimAudioChatEvent;
|
||||
import com.netease.nim.uikit.common.antispam.AntiSpamEvent;
|
||||
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
|
||||
import com.netease.nim.uikit.common.util.AntiSpamUtil;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.netease.nim.uikit.common.util.string.StringUtil;
|
||||
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
|
||||
import com.netease.nim.uikit.impl.NimUIKitImpl;
|
||||
import com.netease.nimlib.sdk.NIMClient;
|
||||
import com.netease.nimlib.sdk.media.record.AudioRecorder;
|
||||
import com.netease.nimlib.sdk.media.record.IAudioRecordCallback;
|
||||
import com.netease.nimlib.sdk.media.record.RecordType;
|
||||
import com.netease.nimlib.sdk.msg.MessageBuilder;
|
||||
import com.netease.nimlib.sdk.msg.MsgService;
|
||||
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
||||
import com.netease.nimlib.sdk.msg.model.CustomNotificationConfig;
|
||||
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 底部文本编辑,语音等模块
|
||||
* Created by hzxuwen on 2015/6/16.
|
||||
*/
|
||||
public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallback, AitTextChangeListener {
|
||||
|
||||
private static final String TAG = "MsgSendLayout";
|
||||
|
||||
private static final int SHOW_LAYOUT_DELAY = 0;
|
||||
|
||||
protected Container container;
|
||||
protected View view;
|
||||
protected Handler uiHandler;
|
||||
|
||||
protected EditText messageEditText;// 文本消息编辑框
|
||||
protected Button audioRecordBtn; // 录音按钮
|
||||
protected View audioAnimLayout; // 录音动画布局
|
||||
protected FrameLayout textAudioSwitchLayout; // 切换文本,语音按钮布局
|
||||
protected View switchToTextButtonInInputBar;// 文本消息选择按钮
|
||||
protected View switchToAudioButtonInInputBar;// 语音消息选择按钮
|
||||
protected View sendMessageButtonInInputBar;// 发送消息按钮
|
||||
protected View emojiButtonInInputBar;// 发送消息按钮
|
||||
protected View messageInputBar;
|
||||
// 表情
|
||||
protected EmoticonPickerView emoticonPickerView; // 贴图表情控件
|
||||
// 语音
|
||||
protected AudioRecorder audioMessageHelper;
|
||||
private AutoHidePanelRecyclerView messageListView;
|
||||
private SessionCustomization customization;
|
||||
private Chronometer time;
|
||||
private TextView timerTip;
|
||||
private LinearLayout timerTipContainer;
|
||||
private boolean started = false;
|
||||
private boolean cancelled = false;
|
||||
private boolean touched = false; // 是否按着
|
||||
private boolean isKeyboardShowed = true; // 是否显示键盘
|
||||
private boolean isTextAudioSwitchShow; // 是否展示左侧语音按钮
|
||||
// adapter
|
||||
private List<BaseAction> actions;
|
||||
// data
|
||||
private long typingTime = 0;
|
||||
private TextWatcher aitTextWatcher;
|
||||
private volatile boolean disable;
|
||||
private boolean isChat;
|
||||
private PanelSwitchHelper mHelper;
|
||||
private final Runnable showTextRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showInputMethod(messageEditText);
|
||||
}
|
||||
};
|
||||
private ImageView ivImage;
|
||||
private ImageView ivCamera;
|
||||
private ImageView ivGift;
|
||||
/**
|
||||
* ************************* 键盘布局切换 *******************************
|
||||
*/
|
||||
|
||||
private final View.OnClickListener clickListener = new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v == switchToTextButtonInInputBar) {
|
||||
switchToTextLayout(true);// 显示文本发送的布局
|
||||
} else if (v == sendMessageButtonInInputBar) {
|
||||
onTextMessageSendButtonPressed();
|
||||
} else if (v == switchToAudioButtonInInputBar) {
|
||||
switchToAudioLayout();
|
||||
} else if (v == ivCamera) {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof CameraAction) {
|
||||
action.onClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mHelper.resetState();
|
||||
} else if (v == ivGift) {
|
||||
|
||||
ivGift.postDelayed(() -> {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof GiftAction) {
|
||||
action.onClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, !mHelper.isResetState() ? 300 : 0);
|
||||
mHelper.resetState();
|
||||
} else if (v == ivImage) {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof PhotoAction) {
|
||||
action.onClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mHelper.resetState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public InputPanel(Container container, View view, List<BaseAction> actions, boolean isTextAudioSwitchShow) {
|
||||
this.container = container;
|
||||
this.view = view;
|
||||
this.actions = actions;
|
||||
this.uiHandler = new Handler();
|
||||
this.isTextAudioSwitchShow = isTextAudioSwitchShow;
|
||||
init();
|
||||
}
|
||||
|
||||
public InputPanel(Container container, View view, List<BaseAction> actions) {
|
||||
this(container, view, actions, true);
|
||||
}
|
||||
|
||||
// 上滑取消录音判断
|
||||
private static boolean isCancelled(View view, MotionEvent event) {
|
||||
int[] location = new int[2];
|
||||
view.getLocationOnScreen(location);
|
||||
|
||||
return event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth()
|
||||
|| event.getRawY() < location[1] - 40;
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
// 停止录音
|
||||
if (audioMessageHelper != null) {
|
||||
onEndAudioRecord(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
// release
|
||||
if (audioMessageHelper != null) {
|
||||
audioMessageHelper.destroyAudioRecorder();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean collapse(boolean immediately) {
|
||||
boolean respond = !mHelper.isResetState();
|
||||
mHelper.resetState();
|
||||
return respond;
|
||||
}
|
||||
|
||||
public void addAitTextWatcher(TextWatcher watcher) {
|
||||
aitTextWatcher = watcher;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
initViews();
|
||||
initInputBarListener();
|
||||
initTextEdit();
|
||||
initAudioRecordButton();
|
||||
restoreText(false);
|
||||
|
||||
for (int i = 0; i < actions.size(); ++i) {
|
||||
actions.get(i).setIndex(i);
|
||||
actions.get(i).setContainer(container);
|
||||
}
|
||||
|
||||
if (disable) {
|
||||
disableButtons();
|
||||
}
|
||||
if (mHelper == null) {
|
||||
mHelper = new PanelSwitchHelper.Builder(container.activity)
|
||||
//可选
|
||||
.addKeyboardStateListener((visible, height) -> {
|
||||
Log.d(TAG, "系统键盘是否可见 : " + visible + " 高度为:" + height);
|
||||
})
|
||||
//可选
|
||||
.addEditTextFocusChangeListener((view, hasFocus) -> {
|
||||
Log.d(TAG, "输入框是否获得焦点 : " + hasFocus);
|
||||
})
|
||||
//可选
|
||||
.addViewClickListener(view -> {
|
||||
if (view == null) return;
|
||||
if (view.getId() == R.id.emoji_button) {
|
||||
switchToTextLayout(false);
|
||||
}
|
||||
Log.d(TAG, "点击了View : " + view);
|
||||
})
|
||||
//可选
|
||||
.addPanelChangeListener(new OnPanelChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onKeyboard() {
|
||||
Log.d(TAG, "唤起系统输入法");
|
||||
container.proxy.onInputPanelExpand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNone() {
|
||||
Log.d(TAG, "隐藏所有面板");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanel(IPanelView view) {
|
||||
Log.d(TAG, "唤起面板 : " + view);
|
||||
container.proxy.onInputPanelExpand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelSizeChange(IPanelView panelView, boolean portrait, int oldWidth, int oldHeight, int width, int height) {
|
||||
|
||||
}
|
||||
})
|
||||
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
@Override
|
||||
public boolean synchronizeKeyboardHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetPanelDefaultHeight() {
|
||||
return ScreenUtil.dip2px(200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPanelTriggerId() {
|
||||
return R.id.iv_image;
|
||||
}
|
||||
})
|
||||
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
@Override
|
||||
public boolean synchronizeKeyboardHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTargetPanelDefaultHeight() {
|
||||
return ScreenUtil.dip2px(200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPanelTriggerId() {
|
||||
return R.id.emoji_button;
|
||||
}
|
||||
})
|
||||
.logTrack(true)//output log
|
||||
.build();
|
||||
|
||||
messageListView.setPanelSwitchHelper(mHelper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setCustomization(SessionCustomization customization) {
|
||||
this.customization = customization;
|
||||
if (customization != null) {
|
||||
emoticonPickerView.setWithSticker(customization.withSticker);
|
||||
}
|
||||
}
|
||||
|
||||
public void reload(Container container, SessionCustomization customization) {
|
||||
this.container = container;
|
||||
setCustomization(customization);
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
messageInputBar = view.findViewById(R.id.textMessageLayout);
|
||||
switchToTextButtonInInputBar = view.findViewById(R.id.buttonTextMessage);
|
||||
switchToAudioButtonInInputBar = view.findViewById(R.id.buttonAudioMessage);
|
||||
emojiButtonInInputBar = view.findViewById(R.id.emoji_button);
|
||||
sendMessageButtonInInputBar = view.findViewById(R.id.buttonSendMessage);
|
||||
messageEditText = view.findViewById(R.id.editTextMessage);
|
||||
|
||||
// 语音
|
||||
audioRecordBtn = view.findViewById(R.id.audioRecord);
|
||||
audioAnimLayout = view.findViewById(R.id.layoutPlayAudio);
|
||||
time = view.findViewById(R.id.timer);
|
||||
timerTip = view.findViewById(R.id.timer_tip);
|
||||
timerTipContainer = view.findViewById(R.id.timer_tip_container);
|
||||
|
||||
// 表情
|
||||
emoticonPickerView = view.findViewById(R.id.emoticon_picker_view);
|
||||
emoticonPickerView.show(this);
|
||||
|
||||
// 显示录音按钮
|
||||
switchToTextButtonInInputBar.setVisibility(View.GONE);
|
||||
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
|
||||
// 文本录音按钮切换布局
|
||||
textAudioSwitchLayout = view.findViewById(R.id.switchLayout);
|
||||
if (isTextAudioSwitchShow) {
|
||||
textAudioSwitchLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
textAudioSwitchLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
messageListView = view.findViewById(R.id.messageListView);
|
||||
ivImage = view.findViewById(R.id.iv_image);
|
||||
ivCamera = view.findViewById(R.id.iv_camera);
|
||||
ivGift = view.findViewById(R.id.iv_gift);
|
||||
ivCamera.setOnClickListener(clickListener);
|
||||
ivGift.setOnClickListener(clickListener);
|
||||
|
||||
}
|
||||
|
||||
public void disableButtons() {
|
||||
if (messageEditText != null && audioRecordBtn != null &&
|
||||
switchToTextButtonInInputBar != null &&
|
||||
switchToAudioButtonInInputBar != null &&
|
||||
emojiButtonInInputBar != null) {
|
||||
messageEditText.setEnabled(false);
|
||||
messageEditText.setHint("禁言中,快找管理员解除禁言吧!");
|
||||
messageEditText.setHintTextColor(Color.parseColor("#999999"));
|
||||
audioRecordBtn.setEnabled(false);
|
||||
switchToTextButtonInInputBar.setEnabled(false);
|
||||
switchToAudioButtonInInputBar.setEnabled(false);
|
||||
emojiButtonInInputBar.setEnabled(false);
|
||||
} else {
|
||||
setDisable(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisable(boolean disable) {
|
||||
this.disable = disable;
|
||||
}
|
||||
|
||||
private void initInputBarListener() {
|
||||
switchToTextButtonInInputBar.setOnClickListener(clickListener);
|
||||
switchToAudioButtonInInputBar.setOnClickListener(clickListener);
|
||||
sendMessageButtonInInputBar.setOnClickListener(clickListener);
|
||||
}
|
||||
|
||||
private void initTextEdit() {
|
||||
messageEditText.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
messageEditText.setImeOptions(EditorInfo.IME_ACTION_SEND);
|
||||
messageEditText.setOnEditorActionListener((v, actionId, event) -> {
|
||||
//当actionId == XX_SEND 或者 XX_DONE时都触发
|
||||
//或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN时也触发
|
||||
//注意,这是一定要判断event != null。因为在某些输入法上会返回null。
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND
|
||||
|| actionId == EditorInfo.IME_ACTION_DONE
|
||||
|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
|
||||
//处理事件
|
||||
onTextMessageSendButtonPressed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
messageEditText.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
messageEditText.setHint("");
|
||||
checkSendButtonEnable(messageEditText);
|
||||
});
|
||||
|
||||
messageEditText.addTextChangedListener(new TextWatcher() {
|
||||
private int start;
|
||||
private int count;
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
this.start = start;
|
||||
this.count = count;
|
||||
if (aitTextWatcher != null) {
|
||||
aitTextWatcher.onTextChanged(s, start, before, count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
if (aitTextWatcher != null) {
|
||||
aitTextWatcher.beforeTextChanged(s, start, count, after);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
checkSendButtonEnable(messageEditText);
|
||||
MoonUtil.replaceEmoticons(container.activity, s, start, count);
|
||||
|
||||
int editEnd = messageEditText.getSelectionEnd();
|
||||
messageEditText.removeTextChangedListener(this);
|
||||
while (StringUtil.counterChars(s.toString()) > NimUIKitImpl.getOptions().maxInputTextLength && editEnd > 0) {
|
||||
s.delete(editEnd - 1, editEnd);
|
||||
editEnd--;
|
||||
}
|
||||
messageEditText.setSelection(Math.min(s.length(), editEnd));
|
||||
messageEditText.addTextChangedListener(this);
|
||||
|
||||
if (aitTextWatcher != null) {
|
||||
aitTextWatcher.afterTextChanged(s);
|
||||
}
|
||||
|
||||
sendTypingCommand();
|
||||
}
|
||||
});
|
||||
|
||||
// 不展示右侧按钮时需要添加edit间距
|
||||
if (!isTextAudioSwitchShow) {
|
||||
try {
|
||||
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) messageEditText.getLayoutParams();
|
||||
layoutParams.setMarginStart(SizeUtils.dp2px(view.getContext(), 12));
|
||||
messageEditText.requestLayout();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送“正在输入”通知
|
||||
*/
|
||||
private void sendTypingCommand() {
|
||||
if (container.account.equals(NimUIKit.getAccount())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (container.sessionType == SessionTypeEnum.Team || container.sessionType == SessionTypeEnum.ChatRoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - typingTime > 5000L) {
|
||||
typingTime = System.currentTimeMillis();
|
||||
CustomNotification command = new CustomNotification();
|
||||
command.setSessionId(container.account);
|
||||
command.setSessionType(container.sessionType);
|
||||
CustomNotificationConfig config = new CustomNotificationConfig();
|
||||
config.enablePush = false;
|
||||
config.enableUnreadCount = false;
|
||||
command.setConfig(config);
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("id", "1");
|
||||
command.setContent(json.toString());
|
||||
|
||||
NIMClient.getService(MsgService.class).sendCustomNotification(command);
|
||||
}
|
||||
}
|
||||
|
||||
// 点击edittext,切换键盘和更多布局
|
||||
private void switchToTextLayout(boolean needShowInput) {
|
||||
audioRecordBtn.setVisibility(View.GONE);
|
||||
messageEditText.setVisibility(View.VISIBLE);
|
||||
switchToTextButtonInInputBar.setVisibility(View.GONE);
|
||||
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
messageInputBar.setVisibility(View.VISIBLE);
|
||||
|
||||
if (needShowInput) {
|
||||
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
// 发送文本消息
|
||||
private void onTextMessageSendButtonPressed() {
|
||||
String text = messageEditText.getText().toString();
|
||||
if (TextUtils.isEmpty(text.trim())) return;
|
||||
EventBus.getDefault().post(new ActiveEvent());
|
||||
IMMessage textMessage = createTextMessage(text);
|
||||
if (AntiSpamUtil.checkLocalAntiSpam(textMessage)) {
|
||||
EventBus.getDefault().post(new AntiSpamEvent());
|
||||
} else {
|
||||
if (container.proxy.sendMessage(textMessage)) {
|
||||
restoreText(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected IMMessage createTextMessage(String text) {
|
||||
return MessageBuilder.createTextMessage(container.account, container.sessionType, text);
|
||||
}
|
||||
|
||||
// 切换成音频,收起键盘,按钮切换成键盘
|
||||
private void switchToAudioLayout() {
|
||||
if (!isChat) {
|
||||
SingleToastUtil.showToast("等级不够");
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "switchToAudioLayout: ");
|
||||
NimAudioChatEvent event = new NimAudioChatEvent();
|
||||
event.setSuccess(o -> {
|
||||
messageEditText.setVisibility(View.GONE);
|
||||
audioRecordBtn.setVisibility(View.VISIBLE);
|
||||
hideInputMethod();
|
||||
switchToAudioButtonInInputBar.setVisibility(View.GONE);
|
||||
switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
mHelper.resetState();
|
||||
});
|
||||
Log.e(TAG, "switchToAudioLayout: post event");
|
||||
EventBus.getDefault().post(event);
|
||||
}
|
||||
|
||||
// 隐藏键盘布局
|
||||
public void hideInputMethod() {
|
||||
isKeyboardShowed = false;
|
||||
uiHandler.removeCallbacks(showTextRunnable);
|
||||
InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
|
||||
messageEditText.clearFocus();
|
||||
}
|
||||
|
||||
// 显示键盘布局
|
||||
private void showInputMethod(EditText editTextMessage) {
|
||||
editTextMessage.requestFocus();
|
||||
//如果已经显示,则继续操作时不需要把光标定位到最后
|
||||
if (!isKeyboardShowed) {
|
||||
editTextMessage.setSelection(editTextMessage.getText().length());
|
||||
isKeyboardShowed = true;
|
||||
}
|
||||
|
||||
mHelper.toKeyboardState();
|
||||
container.proxy.onInputPanelExpand();
|
||||
}
|
||||
|
||||
private void restoreText(boolean clearText) {
|
||||
if (clearText) {
|
||||
messageEditText.setText("");
|
||||
}
|
||||
checkSendButtonEnable(messageEditText);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示发送或更多
|
||||
*
|
||||
* @param editText
|
||||
*/
|
||||
private void checkSendButtonEnable(EditText editText) {
|
||||
String textMessage = editText.getText().toString();
|
||||
setEditTextState();
|
||||
if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage)) && editText.hasFocus()) {
|
||||
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
sendMessageButtonInInputBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* *************** IEmojiSelectedListener ***************
|
||||
*/
|
||||
@Override
|
||||
public void onEmojiSelected(String key) {
|
||||
Editable mEditable = messageEditText.getText();
|
||||
if (key.equals("/DEL")) {
|
||||
messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
|
||||
} else {
|
||||
int start = messageEditText.getSelectionStart();
|
||||
int end = messageEditText.getSelectionEnd();
|
||||
start = (start < 0 ? 0 : start);
|
||||
end = (start < 0 ? 0 : end);
|
||||
mEditable.replace(start, end, key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStickerSelected(String category, String item) {
|
||||
Log.i("InputPanel", "onStickerSelected, category =" + category + ", sticker =" + item);
|
||||
|
||||
if (customization != null) {
|
||||
MsgAttachment attachment = customization.createStickerAttachment(category, item);
|
||||
IMMessage stickerMessage = MessageBuilder.createCustomMessage(container.account, container.sessionType, "贴图消息", attachment);
|
||||
container.proxy.sendMessage(stickerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextAdd(String content, int start, int length) {
|
||||
if (messageEditText.getVisibility() != View.VISIBLE ||
|
||||
(emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE)) {
|
||||
switchToTextLayout(true);
|
||||
} else {
|
||||
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
|
||||
}
|
||||
messageEditText.getEditableText().insert(start, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextDelete(int start, int length) {
|
||||
if (messageEditText.getVisibility() != View.VISIBLE) {
|
||||
switchToTextLayout(true);
|
||||
} else {
|
||||
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
|
||||
}
|
||||
int end = start + length - 1;
|
||||
messageEditText.getEditableText().replace(start, end, "");
|
||||
}
|
||||
|
||||
public int getEditSelectionStart() {
|
||||
return messageEditText.getSelectionStart();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ****************************** 语音 ***********************************
|
||||
*/
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void initAudioRecordButton() {
|
||||
audioRecordBtn.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
touched = true;
|
||||
initAudioRecord();
|
||||
onStartAudioRecord();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL
|
||||
|| event.getAction() == MotionEvent.ACTION_UP) {
|
||||
touched = false;
|
||||
onEndAudioRecord(isCancelled(v, event));
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
touched = true;
|
||||
cancelAudioRecord(isCancelled(v, event));
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化AudioRecord
|
||||
*/
|
||||
private void initAudioRecord() {
|
||||
if (audioMessageHelper == null) {
|
||||
UIKitOptions options = NimUIKitImpl.getOptions();
|
||||
audioMessageHelper = new AudioRecorder(container.activity, options.audioRecordType, options.audioRecordMaxTime, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始语音录制
|
||||
*/
|
||||
private void onStartAudioRecord() {
|
||||
container.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
audioMessageHelper.startRecord();
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束语音录制
|
||||
*
|
||||
* @param cancel
|
||||
*/
|
||||
private void onEndAudioRecord(boolean cancel) {
|
||||
started = false;
|
||||
container.activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
audioMessageHelper.completeRecord(cancel);
|
||||
audioRecordBtn.setText(R.string.record_audio);
|
||||
audioRecordBtn.setBackgroundResource(R.drawable.bg_message_voice);
|
||||
stopAudioRecordAnim();
|
||||
|
||||
if (!cancel) {
|
||||
EventBus.getDefault().post(new ActiveEvent());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消语音录制
|
||||
*
|
||||
* @param cancel
|
||||
*/
|
||||
private void cancelAudioRecord(boolean cancel) {
|
||||
// reject
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
// no change
|
||||
if (cancelled == cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelled = cancel;
|
||||
updateTimerTip(cancel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正在进行语音录制和取消语音录制,界面展示
|
||||
*
|
||||
* @param cancel
|
||||
*/
|
||||
private void updateTimerTip(boolean cancel) {
|
||||
if (cancel) {
|
||||
timerTip.setText(R.string.recording_cancel_tip);
|
||||
timerTipContainer.setBackgroundResource(R.drawable.nim_cancel_record_red_bg);
|
||||
} else {
|
||||
timerTip.setText(R.string.recording_cancel);
|
||||
timerTipContainer.setBackgroundResource(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始语音录制动画
|
||||
*/
|
||||
private void playAudioRecordAnim() {
|
||||
audioAnimLayout.setVisibility(View.VISIBLE);
|
||||
time.setBase(SystemClock.elapsedRealtime());
|
||||
time.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束语音录制动画
|
||||
*/
|
||||
private void stopAudioRecordAnim() {
|
||||
audioAnimLayout.setVisibility(View.GONE);
|
||||
time.stop();
|
||||
time.setBase(SystemClock.elapsedRealtime());
|
||||
}
|
||||
|
||||
// 录音状态回调
|
||||
@Override
|
||||
public void onRecordReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecordStart(File audioFile, RecordType recordType) {
|
||||
started = true;
|
||||
if (!touched) {
|
||||
return;
|
||||
}
|
||||
|
||||
audioRecordBtn.setText(R.string.record_audio_end);
|
||||
audioRecordBtn.setBackgroundResource(R.drawable.bg_message_voice_pressed);
|
||||
|
||||
updateTimerTip(false); // 初始化语音动画状态
|
||||
playAudioRecordAnim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecordSuccess(File audioFile, long audioLength, RecordType recordType) {
|
||||
IMMessage audioMessage = MessageBuilder.createAudioMessage(container.account, container.sessionType, audioFile, audioLength);
|
||||
container.proxy.sendMessage(audioMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecordFail() {
|
||||
if (started) {
|
||||
SingleToastUtil.showToast(R.string.recording_error);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecordCancel() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecordReachedMaxTime(final int maxTime) {
|
||||
stopAudioRecordAnim();
|
||||
EasyAlertDialogHelper.createOkCancelDiolag(container.activity, "", container.activity.getString(R.string.recording_max_time), false, new EasyAlertDialogHelper.OnDialogActionListener() {
|
||||
@Override
|
||||
public void doCancelAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doOkAction() {
|
||||
audioMessageHelper.handleEndRecord(true, maxTime);
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
return audioMessageHelper != null && audioMessageHelper.isRecording();
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
int index = (requestCode << 16) >> 24;
|
||||
if (index != 0) {
|
||||
index--;
|
||||
if (index < 0 | index >= actions.size()) {
|
||||
LogUtil.d(TAG, "request code out of actions' range");
|
||||
return;
|
||||
}
|
||||
BaseAction action = actions.get(index);
|
||||
if (action != null) {
|
||||
action.onActivityResult(requestCode & 0xff, resultCode, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadActions(List<BaseAction> actions) {
|
||||
this.actions = actions;
|
||||
for (int i = 0; i < this.actions.size(); ++i) {
|
||||
this.actions.get(i).setIndex(i);
|
||||
this.actions.get(i).setContainer(container);
|
||||
}
|
||||
ActionsPanel.init(view, actions);
|
||||
}
|
||||
|
||||
public void setLimitLevel(boolean isChat, String msg) {
|
||||
this.isChat = isChat;
|
||||
setEditTextState();
|
||||
}
|
||||
|
||||
private void setEditTextState() {
|
||||
if (!isChat) {
|
||||
messageEditText.setHint("暂未达到可发起私聊等级");
|
||||
messageEditText.setFocusable(false);
|
||||
messageEditText.setFocusableInTouchMode(false);
|
||||
messageEditText.setEnabled(false);
|
||||
sendMessageButtonInInputBar.setEnabled(false);
|
||||
} else {
|
||||
messageEditText.setHint("请输入消息");
|
||||
messageEditText.setFocusable(true);
|
||||
messageEditText.setFocusableInTouchMode(true);
|
||||
messageEditText.setEnabled(true);
|
||||
sendMessageButtonInInputBar.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -17,6 +17,8 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.mango.core.room.event.MessageSizeEvent;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.netease.nim.uikit.R;
|
||||
import com.netease.nim.uikit.api.NimUIKit;
|
||||
import com.netease.nim.uikit.api.model.user.UserInfoObserver;
|
||||
@@ -65,8 +67,6 @@ import com.netease.nimlib.sdk.robot.model.RobotAttachment;
|
||||
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
||||
import com.netease.nimlib.sdk.team.constant.TeamMemberType;
|
||||
import com.netease.nimlib.sdk.team.model.TeamMember;
|
||||
import com.mango.core.room.event.MessageSizeEvent;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class MessageListPanelEx {
|
||||
private static final int REQUEST_CODE_FORWARD_TEAM = 0x02;
|
||||
// 背景图片缓存
|
||||
private static Pair<String, Bitmap> background;
|
||||
private static Comparator<IMMessage> comp = new Comparator<IMMessage>() {
|
||||
private static final Comparator<IMMessage> comp = new Comparator<IMMessage>() {
|
||||
|
||||
@Override
|
||||
public int compare(IMMessage o1, IMMessage o2) {
|
||||
@@ -97,7 +97,7 @@ public class MessageListPanelEx {
|
||||
};
|
||||
// container
|
||||
private Container container;
|
||||
private View rootView;
|
||||
private final View rootView;
|
||||
// message list view
|
||||
private RecyclerView messageListView;
|
||||
private List<IMMessage> items;
|
||||
@@ -107,15 +107,15 @@ public class MessageListPanelEx {
|
||||
private IncomingMsgPrompt incomingMsgPrompt;
|
||||
private Handler uiHandler;
|
||||
// 仅显示消息记录,不接收和发送消息
|
||||
private boolean recordOnly;
|
||||
private final boolean recordOnly;
|
||||
// 从服务器拉取消息记录
|
||||
private boolean remote;
|
||||
private final boolean remote;
|
||||
// 语音转文字
|
||||
private VoiceTrans voiceTrans;
|
||||
// 待转发消息
|
||||
private IMMessage forwardMessage;
|
||||
private CountDownTimer countDownTimer;
|
||||
private OnItemClickListener listener = new OnItemClickListener() {
|
||||
private final OnItemClickListener listener = new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(IRecyclerView adapter, View view, int position) {
|
||||
|
||||
@@ -142,7 +142,7 @@ public class MessageListPanelEx {
|
||||
container.activity.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
// Toast.makeText(container.activity, "路径错误", Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort("路径错误");
|
||||
SingleToastUtil.showToast("路径错误");
|
||||
}
|
||||
|
||||
} else if (LinkElement.TYPE_BLOCK.equals(element.getType())) {
|
||||
@@ -162,7 +162,7 @@ public class MessageListPanelEx {
|
||||
/**
|
||||
* 消息状态变化观察者
|
||||
*/
|
||||
private Observer<IMMessage> messageStatusObserver = new Observer<IMMessage>() {
|
||||
private final Observer<IMMessage> messageStatusObserver = new Observer<IMMessage>() {
|
||||
@Override
|
||||
public void onEvent(IMMessage message) {
|
||||
if (isMyMessage(message)) {
|
||||
@@ -173,7 +173,7 @@ public class MessageListPanelEx {
|
||||
/**
|
||||
* 消息附件上传/下载进度观察者
|
||||
*/
|
||||
private Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
|
||||
private final Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
|
||||
@Override
|
||||
public void onEvent(AttachmentProgress progress) {
|
||||
onAttachmentProgressChange(progress);
|
||||
@@ -182,7 +182,7 @@ public class MessageListPanelEx {
|
||||
/**
|
||||
* 本地消息接收观察者
|
||||
*/
|
||||
private MessageListPanelHelper.LocalMessageObserver incomingLocalMessageObserver = new MessageListPanelHelper.LocalMessageObserver() {
|
||||
private final MessageListPanelHelper.LocalMessageObserver incomingLocalMessageObserver = new MessageListPanelHelper.LocalMessageObserver() {
|
||||
@Override
|
||||
public void onAddMessage(IMMessage message) {
|
||||
if (message == null || !container.account.equals(message.getSessionId())) {
|
||||
@@ -202,7 +202,7 @@ public class MessageListPanelEx {
|
||||
/**
|
||||
* 消息撤回观察者
|
||||
*/
|
||||
private Observer<RevokeMsgNotification> revokeMessageObserver = new Observer<RevokeMsgNotification>() {
|
||||
private final Observer<RevokeMsgNotification> revokeMessageObserver = new Observer<RevokeMsgNotification>() {
|
||||
@Override
|
||||
public void onEvent(RevokeMsgNotification notification) {
|
||||
if (notification == null || notification.getMessage() == null) {
|
||||
@@ -282,10 +282,10 @@ public class MessageListPanelEx {
|
||||
}
|
||||
|
||||
private void initListView(IMMessage anchor) {
|
||||
listviewBk = (ImageView) rootView.findViewById(R.id.message_activity_background);
|
||||
listviewBk = rootView.findViewById(R.id.message_activity_background);
|
||||
|
||||
// RecyclerView
|
||||
messageListView = (RecyclerView) rootView.findViewById(R.id.messageListView);
|
||||
messageListView = rootView.findViewById(R.id.messageListView);
|
||||
messageListView.setLayoutManager(new LinearLayoutManager(container.activity));
|
||||
messageListView.requestDisallowInterceptTouchEvent(true);
|
||||
messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@@ -339,12 +339,7 @@ public class MessageListPanelEx {
|
||||
}
|
||||
|
||||
public void scrollToBottom() {
|
||||
uiHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doScrollToBottom();
|
||||
}
|
||||
}, 200);
|
||||
doScrollToBottom();
|
||||
}
|
||||
|
||||
private void doScrollToBottom() {
|
||||
@@ -603,15 +598,11 @@ public class MessageListPanelEx {
|
||||
}
|
||||
|
||||
private boolean receiveReceiptCheck(final IMMessage msg) {
|
||||
if (msg != null && msg.getSessionType() == SessionTypeEnum.P2P
|
||||
return msg != null && msg.getSessionType() == SessionTypeEnum.P2P
|
||||
&& msg.getDirect() == MsgDirectionEnum.Out
|
||||
&& msg.getMsgType() != MsgTypeEnum.tip
|
||||
&& msg.getMsgType() != MsgTypeEnum.notification
|
||||
&& msg.isRemoteRead()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
&& msg.isRemoteRead();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -649,12 +640,8 @@ public class MessageListPanelEx {
|
||||
}
|
||||
|
||||
private boolean sendReceiptCheck(final IMMessage msg) {
|
||||
if (msg == null || msg.getDirect() != MsgDirectionEnum.In ||
|
||||
msg.getMsgType() == MsgTypeEnum.tip || msg.getMsgType() == MsgTypeEnum.notification) {
|
||||
return false; // 非收到的消息,Tip消息和通知类消息,不要发已读回执
|
||||
}
|
||||
|
||||
return true;
|
||||
return msg != null && msg.getDirect() == MsgDirectionEnum.In &&
|
||||
msg.getMsgType() != MsgTypeEnum.tip && msg.getMsgType() != MsgTypeEnum.notification; // 非收到的消息,Tip消息和通知类消息,不要发已读回执
|
||||
}
|
||||
|
||||
// 删除消息
|
||||
@@ -699,7 +686,7 @@ public class MessageListPanelEx {
|
||||
|
||||
if (message == null) {
|
||||
// Toast.makeText(container.activity, "该类型不支持转发", Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort("该类型不支持转发");
|
||||
SingleToastUtil.showToast("该类型不支持转发");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -742,15 +729,15 @@ public class MessageListPanelEx {
|
||||
|
||||
private class MessageLoader implements BaseFetchLoadAdapter.RequestLoadMoreListener, BaseFetchLoadAdapter.RequestFetchMoreListener {
|
||||
|
||||
private int loadMsgCount = NimUIKitImpl.getOptions().messageCountLoadOnce;
|
||||
private final int loadMsgCount = NimUIKitImpl.getOptions().messageCountLoadOnce;
|
||||
|
||||
private QueryDirectionEnum direction = null;
|
||||
|
||||
private IMMessage anchor;
|
||||
private boolean remote;
|
||||
private final IMMessage anchor;
|
||||
private final boolean remote;
|
||||
|
||||
private boolean firstLoad = true;
|
||||
private RequestCallback<List<IMMessage>> callback = new RequestCallbackWrapper<List<IMMessage>>() {
|
||||
private final RequestCallback<List<IMMessage>> callback = new RequestCallbackWrapper<List<IMMessage>>() {
|
||||
@Override
|
||||
public void onResult(int code, List<IMMessage> messages, Throwable exception) {
|
||||
if (code != ResponseCode.RES_SUCCESS || exception != null) {
|
||||
@@ -1209,8 +1196,7 @@ public class MessageListPanelEx {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
// Toast.makeText(container.activity, finalContent, Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort(finalContent);
|
||||
SingleToastUtil.showToast(finalContent);
|
||||
setEarPhoneMode(!UserPreferences.isEarPhoneModeEnable(), true);
|
||||
}
|
||||
});
|
||||
@@ -1257,8 +1243,7 @@ public class MessageListPanelEx {
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (!NetworkUtil.isNetAvailable(container.activity)) {
|
||||
// Toast.makeText(container.activity, R.string.network_is_not_available, Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort(R.string.network_is_not_available);
|
||||
SingleToastUtil.showToast(R.string.network_is_not_available);
|
||||
return;
|
||||
}
|
||||
NIMClient.getService(MsgService.class).revokeMessage(item).setCallback(new RequestCallback<Void>() {
|
||||
@@ -1271,11 +1256,9 @@ public class MessageListPanelEx {
|
||||
@Override
|
||||
public void onFailed(int code) {
|
||||
if (code == ResponseCode.RES_OVERDUE) {
|
||||
// Toast.makeText(container.activity, R.string.revoke_failed, Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort(R.string.revoke_failed);
|
||||
SingleToastUtil.showToast(R.string.revoke_failed);
|
||||
} else {
|
||||
// Toast.makeText(container.activity, "revoke msg failed, code:" + code, Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToastShort("revoke msg failed, code:" + code);
|
||||
SingleToastUtil.showToast("revoke msg failed, code:" + code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,31 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.mango.core.audio.event.VoiceShakeHeartEvent;
|
||||
import com.mango.core.auth.AuthModel;
|
||||
import com.mango.core.im.friend.IMFriendModel;
|
||||
import com.mango.core.mentoring_relationship.event.MentoringSuccessEvent;
|
||||
import com.mango.core.noble.NobleUtil;
|
||||
import com.mango.core.praise.PraiseModel;
|
||||
import com.mango.core.praise.event.IsLikedEvent;
|
||||
import com.mango.core.praise.event.PraiseEvent;
|
||||
import com.mango.core.user.UserModel;
|
||||
import com.mango.core.user.bean.UserDetailInfo;
|
||||
import com.mango.core.user.bean.UserInfo;
|
||||
import com.mango.core.utils.StringExtensionKt;
|
||||
import com.mango.core.utils.SystemUidUtil;
|
||||
import com.mango.core.utils.net.BeanObserver;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.avroom.activity.AVRoomActivity;
|
||||
import com.mango.moshen.common.widget.CustomImageSpan;
|
||||
import com.mango.moshen.mentoring_relationship.dialog.BuildMentoringRelationshipSuccessDialog;
|
||||
import com.mango.moshen.ui.im.audio.ShakeHeartDialogFragment;
|
||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||
import com.mango.moshen.ui.user.UserInfoActivity;
|
||||
import com.mango.moshen.ui.utils.ImageLoadUtils;
|
||||
import com.mango.xchat_android_library.utils.ListUtils;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.netease.nim.uikit.StatusBarUtil;
|
||||
import com.netease.nim.uikit.api.NimUIKit;
|
||||
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
|
||||
import com.netease.nim.uikit.api.model.main.OnlineStateChangeObserver;
|
||||
@@ -31,33 +56,6 @@ import com.netease.nimlib.sdk.Observer;
|
||||
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.avroom.activity.AVRoomActivity;
|
||||
import com.mango.moshen.common.widget.CustomImageSpan;
|
||||
import com.mango.moshen.ui.im.audio.ShakeHeartDialogFragment;
|
||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||
import com.mango.moshen.ui.user.UserInfoActivity;
|
||||
import com.mango.moshen.ui.utils.ImageLoadUtils;
|
||||
import com.mango.moshen.mentoring_relationship.dialog.BuildMentoringRelationshipSuccessDialog;
|
||||
import com.mango.core.audio.event.VoiceShakeHeartEvent;
|
||||
import com.mango.core.auth.AuthModel;
|
||||
import com.mango.core.im.friend.IMFriendModel;
|
||||
import com.mango.core.initial.InitialModel;
|
||||
import com.mango.core.initial.bean.InitInfo;
|
||||
import com.mango.core.level.UserLevelVo;
|
||||
import com.mango.core.mentoring_relationship.event.MentoringSuccessEvent;
|
||||
import com.mango.core.noble.NobleUtil;
|
||||
import com.mango.core.praise.PraiseModel;
|
||||
import com.mango.core.praise.event.IsLikedEvent;
|
||||
import com.mango.core.praise.event.PraiseEvent;
|
||||
import com.mango.core.user.UserModel;
|
||||
import com.mango.core.user.bean.UserDetailInfo;
|
||||
import com.mango.core.user.bean.UserInfo;
|
||||
import com.mango.core.utils.StringExtensionKt;
|
||||
import com.mango.core.utils.SystemUidUtil;
|
||||
import com.mango.core.utils.net.BeanObserver;
|
||||
import com.mango.xchat_android_library.utils.ListUtils;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
@@ -414,21 +412,6 @@ public class NimP2PMessageActivity extends NewBaseMessageActivity {
|
||||
MessageFragment fragment = new MessageFragment();
|
||||
fragment.setArguments(arguments);
|
||||
fragment.setContainerId(R.id.message_fragment_container);
|
||||
|
||||
// 等级限制:官方小秘书 和 系统消息,不设置等级限制
|
||||
if (!SystemUidUtil.isSystemUid(sessionId)) {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (userInfo != null) {
|
||||
UserLevelVo userLevelVo = userInfo.getUserLevelVo();
|
||||
if (userLevelVo != null) {
|
||||
fragment.setCurrentLevel(userLevelVo.experLevelSeq);
|
||||
}
|
||||
}
|
||||
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
|
||||
if (initInfo != null) {
|
||||
fragment.setLimitLevel(initInfo.getPrivateChatLevelNo());
|
||||
}
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@@ -486,4 +469,16 @@ public class NimP2PMessageActivity extends NewBaseMessageActivity {
|
||||
ShakeHeartDialogFragment shakeHeartDialogFragment = ShakeHeartDialogFragment.newInstance(event.showTextHint);
|
||||
shakeHeartDialogFragment.show(getSupportFragmentManager(), "shake_heart");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needSteepStateBar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStatusBar() {
|
||||
super.setStatusBar();
|
||||
StatusBarUtil.transparencyBar(this);
|
||||
StatusBarUtil.StatusBarLightMode(this);
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,24 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mango.core.UriProvider;
|
||||
import com.mango.core.auth.AuthModel;
|
||||
import com.mango.core.im.chatterbox.ChatterBoxHelper;
|
||||
import com.mango.core.im.chatterbox.HideInputEvent;
|
||||
import com.mango.core.room.event.MessageSizeEvent;
|
||||
import com.mango.core.statistic.StatisticManager;
|
||||
import com.mango.core.statistic.protocol.StatisticsProtocol;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.common.widget.OriginalDrawStatusClickSpan;
|
||||
import com.mango.moshen.ui.im.GreetPresenter;
|
||||
import com.mango.moshen.ui.im.InputPanel;
|
||||
import com.mango.moshen.ui.im.MessageListPanelEx;
|
||||
import com.mango.moshen.ui.im.chat.MVHChatterBoxStart;
|
||||
import com.mango.moshen.ui.im.model.IMCustomModel;
|
||||
import com.mango.moshen.ui.webview.CommonWebViewActivity;
|
||||
import com.mango.moshen.utils.PushMessageHandler;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.mango.xchat_android_library.utils.config.BasicConfig;
|
||||
import com.netease.nim.uikit.api.UIKitOptions;
|
||||
import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
|
||||
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
||||
@@ -28,7 +46,6 @@ import com.netease.nim.uikit.business.session.actions.BaseAction;
|
||||
import com.netease.nim.uikit.business.session.constant.Extras;
|
||||
import com.netease.nim.uikit.business.session.module.Container;
|
||||
import com.netease.nim.uikit.business.session.module.ModuleProxy;
|
||||
import com.netease.nim.uikit.business.session.module.input.InputPanel;
|
||||
import com.netease.nim.uikit.business.session.module.input.NimAudioChatEvent;
|
||||
import com.netease.nim.uikit.business.session.module.input.NimImageActionEvent;
|
||||
import com.netease.nim.uikit.common.fragment.TFragment;
|
||||
@@ -51,25 +68,6 @@ import com.netease.nimlib.sdk.robot.model.NimRobotInfo;
|
||||
import com.netease.nimlib.sdk.robot.model.RobotAttachment;
|
||||
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
||||
import com.tbruyelle.rxpermissions2.RxPermissions;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.common.widget.OriginalDrawStatusClickSpan;
|
||||
import com.mango.moshen.ui.im.GreetPresenter;
|
||||
import com.mango.moshen.ui.im.MessageListPanelEx;
|
||||
import com.mango.moshen.ui.im.chat.MVHChatterBoxStart;
|
||||
import com.mango.moshen.ui.im.model.IMCustomModel;
|
||||
import com.mango.moshen.ui.webview.CommonWebViewActivity;
|
||||
import com.mango.moshen.utils.PushMessageHandler;
|
||||
import com.mango.core.UriProvider;
|
||||
import com.mango.core.auth.AuthModel;
|
||||
import com.mango.core.im.chatterbox.ChatterBoxHelper;
|
||||
import com.mango.core.im.chatterbox.HideInputEvent;
|
||||
import com.mango.core.im.custom.bean.CustomAttachment;
|
||||
import com.mango.core.im.custom.bean.ImTipAttachment;
|
||||
import com.mango.core.room.event.MessageSizeEvent;
|
||||
import com.mango.core.statistic.StatisticManager;
|
||||
import com.mango.core.statistic.protocol.StatisticsProtocol;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.mango.xchat_android_library.utils.config.BasicConfig;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
@@ -103,6 +101,7 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
protected InputPanel inputPanel;
|
||||
protected MessageListPanelEx messageListPanel;
|
||||
protected AitManager aitManager;
|
||||
private boolean inRoom;
|
||||
/**
|
||||
* 消息接收观察者
|
||||
*/
|
||||
@@ -190,27 +189,12 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送提示信息
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public void sendTipMessage(String msg, int second) {
|
||||
ImTipAttachment attachment = new ImTipAttachment(CustomAttachment.CUSTOM_MSG_IM_TIP, second);
|
||||
attachment.setMsg(msg);
|
||||
IMMessage message = MessageBuilder.createCustomMessage(sessionId, SessionTypeEnum.P2P, attachment);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
public boolean onBackPressed() {
|
||||
if (inputPanel.collapse(true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (messageListPanel.onBackPressed()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return messageListPanel.onBackPressed();
|
||||
}
|
||||
|
||||
public void refreshMessageList() {
|
||||
@@ -243,8 +227,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
|
||||
initAitManager();
|
||||
|
||||
inputPanel.switchRobotMode(NimUIKitImpl.getRobotInfoProvider().getRobotByAccount(sessionId) != null);
|
||||
|
||||
registerObservers(true);
|
||||
|
||||
if (customization != null) {
|
||||
@@ -302,7 +284,7 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
*/
|
||||
// 是否允许发送消息
|
||||
protected boolean isAllowSendMessage(final IMMessage message) {
|
||||
return true;
|
||||
return isChat;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,7 +306,9 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
*/
|
||||
@Override
|
||||
public boolean sendMessage(IMMessage message) {
|
||||
|
||||
if (!isAllowSendMessage(message)) {
|
||||
SingleToastUtil.showToast("未到达私聊等级!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -346,8 +330,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
|
||||
final IMMessage msg = message;
|
||||
appendPushConfig(message);
|
||||
// send message to server and save to db
|
||||
IMMessage finalMessage = message;
|
||||
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void param) {
|
||||
@@ -542,10 +524,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
// 操作面板集合
|
||||
protected List<BaseAction> getActionList() {
|
||||
List<BaseAction> actions = new ArrayList<>();
|
||||
// actions.add(new ImageAction());
|
||||
// actions.add(new VideoAction());
|
||||
// actions.add(new LocationAction());
|
||||
|
||||
if (customization != null && customization.actions != null) {
|
||||
actions.addAll(customization.actions);
|
||||
}
|
||||
@@ -566,18 +544,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
messageListPanel.receiveReceipt();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载 输入面板
|
||||
*
|
||||
* @param sessionCustomization
|
||||
*/
|
||||
public void reloadInputPanel(SessionCustomization sessionCustomization) {
|
||||
this.customization = sessionCustomization;
|
||||
Container container = new Container(getActivity(), sessionId, sessionType, this);
|
||||
inputPanel.reload(container, customization);
|
||||
inputPanel.reloadActions(sessionCustomization.actions);
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onHideInput(HideInputEvent event) {
|
||||
if (inputPanel != null) {
|
||||
@@ -592,51 +558,54 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
if (inputPanel != null) {
|
||||
if (event.getSize() > 0) {
|
||||
tvChatLimit.setVisibility(View.GONE);
|
||||
isChat = true;
|
||||
inputPanel.setLimitLevel(true, "");
|
||||
} else {
|
||||
IMCustomModel.get().getPrivateChatLimit(sessionId).subscribe(((privateChatLimitInfo, throwable) -> {
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
} else {
|
||||
isChat = privateChatLimitInfo.isChat();
|
||||
hintText = "暂未达到可发起私聊等级";
|
||||
inputPanel.setLimitLevel(privateChatLimitInfo.isChat(), privateChatLimitInfo.getMessage());
|
||||
IMCustomModel.get()
|
||||
.getPrivateChatLimit(sessionId)
|
||||
.subscribe(((privateChatLimitInfo, throwable) -> {
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
} else {
|
||||
isChat = privateChatLimitInfo.isChat();
|
||||
hintText = "暂未达到可发起私聊等级";
|
||||
inputPanel.setLimitLevel(privateChatLimitInfo.isChat(), privateChatLimitInfo.getMessage());
|
||||
|
||||
String experLevel = "财富等级≥" + privateChatLimitInfo.getWealthLevel();
|
||||
String charmLevel = "魅力等级≥" + privateChatLimitInfo.getCharmLevel();
|
||||
String privacyAgreementDescTip = getContext().getString(R.string.text_chat_limit, experLevel, charmLevel);
|
||||
SpannableString ss = new SpannableString(privacyAgreementDescTip);
|
||||
int experLevelIndex = privacyAgreementDescTip.indexOf(experLevel);
|
||||
int charmLevelIndex = privacyAgreementDescTip.indexOf(charmLevel);
|
||||
String experLevel = "财富等级≥" + privateChatLimitInfo.getWealthLevel();
|
||||
String charmLevel = "魅力等级≥" + privateChatLimitInfo.getCharmLevel();
|
||||
String privacyAgreementDescTip = getContext().getString(R.string.text_chat_limit, experLevel, charmLevel);
|
||||
SpannableString ss = new SpannableString(privacyAgreementDescTip);
|
||||
int experLevelIndex = privacyAgreementDescTip.indexOf(experLevel);
|
||||
int charmLevelIndex = privacyAgreementDescTip.indexOf(charmLevel);
|
||||
|
||||
|
||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
if (widget instanceof TextView)
|
||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
if (widget instanceof TextView)
|
||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||
|
||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||
}
|
||||
}, experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), charmLevelIndex, charmLevelIndex + charmLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
if (widget instanceof TextView)
|
||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||
|
||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||
}
|
||||
}, charmLevelIndex, charmLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
|
||||
tvChatLimit.setText(ss);
|
||||
tvChatLimit.setHighlightColor(Color.TRANSPARENT);
|
||||
tvChatLimit.setMovementMethod(new LinkMovementMethod());
|
||||
tvChatLimit.setVisibility(isChat ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}, experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), charmLevelIndex, charmLevelIndex + charmLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
if (widget instanceof TextView)
|
||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||
|
||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||
}
|
||||
}, charmLevelIndex, charmLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
|
||||
tvChatLimit.setText(ss);
|
||||
tvChatLimit.setHighlightColor(Color.TRANSPARENT);
|
||||
tvChatLimit.setMovementMethod(new LinkMovementMethod());
|
||||
tvChatLimit.setVisibility(isChat ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -672,12 +641,4 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
||||
});
|
||||
}
|
||||
|
||||
public void setLimitLevel(int limitLevel) {
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
public void setCurrentLevel(int currentLevel) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,7 +4,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_normal_1c1b22">
|
||||
android:background="@color/bg_normal_1c1b22"
|
||||
android:paddingTop="30dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.netease.nim.uikit.business.session.emoji.EmoticonPickerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/emoticon_picker_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
|
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nim_message_item_text_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="phone|email|web"
|
||||
android:gravity="center_vertical|left"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="3dip"
|
||||
android:maxWidth="222dp"
|
||||
android:text="这是选择图片的玩意"
|
||||
android:textColor="@color/text_title_white"
|
||||
android:textSize="@dimen/dp_13" />
|
||||
|
||||
</LinearLayout>
|
@@ -1,58 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.effective.android.panel.view.PanelSwitchLayout 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/messageActivityLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_normal_1c1b22"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
app:animationSpeed="standard">
|
||||
|
||||
<RelativeLayout
|
||||
<com.effective.android.panel.view.content.LinearContentContainer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_game"
|
||||
android:layout_width="299dp"
|
||||
android:layout_height="163dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="-10dp"
|
||||
android:background="@drawable/chat_popup_game_bg"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="25dp"
|
||||
android:text="Ta爱玩的游戏"
|
||||
android:textColor="#ff666666"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_close"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="right"
|
||||
android:layout_marginRight="10dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/chat_popup_game_close" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="55dp" />
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:edit_view="@id/editTextMessage">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/message_activity_list_view_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/fl_game"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.netease.nim.uikit.business.session.helper.MsgBkImageView
|
||||
@@ -72,7 +38,7 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
<com.mango.moshen.ui.im.AutoHidePanelRecyclerView
|
||||
android:id="@+id/messageListView"
|
||||
style="@style/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
@@ -120,18 +86,173 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
android:text="哈哈哈哈哈"
|
||||
android:paddingStart="@dimen/dp_10"
|
||||
android:paddingEnd="@dimen/dp_10"
|
||||
android:paddingTop="@dimen/dp_2"
|
||||
android:paddingBottom="@dimen/dp_2"
|
||||
android:background="@drawable/bg_chat_limit"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
android:paddingStart="@dimen/dp_10"
|
||||
android:paddingTop="@dimen/dp_2"
|
||||
android:paddingEnd="@dimen/dp_10"
|
||||
android:paddingBottom="@dimen/dp_2"
|
||||
android:text="哈哈哈哈哈"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/textMessageLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/bottom_component_margin_vertical"
|
||||
android:paddingBottom="@dimen/bottom_component_margin_vertical">
|
||||
|
||||
<include layout="@layout/nim_message_activity_bottom_layout" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/switchLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/bottom_component_margin_horizontal"
|
||||
android:layout_marginRight="@dimen/bottom_component_margin_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonAudioMessage"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/nim_message_button_bottom_audio_selector"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonTextMessage"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/nim_message_button_bottom_text_selector"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/audioRecord"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_message_voice"
|
||||
android:text="@string/record_audio"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/editTextMessage"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:autoLink="web|email|phone"
|
||||
android:background="@drawable/bg_message_input"
|
||||
android:hint="@string/message_hint"
|
||||
android:imeOptions="actionSend"
|
||||
android:inputType="text"
|
||||
android:maxLength="120"
|
||||
android:maxLines="4"
|
||||
android:paddingStart="@dimen/dp_10"
|
||||
android:paddingEnd="10dp"
|
||||
android:textColor="@color/color_C6C6E9"
|
||||
android:textColorHint="@color/text_hint_555574"
|
||||
android:textCursorDrawable="@null"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/emoji_button"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:background="@drawable/nim_message_button_bottom_emoji_selector"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/buttonSendMessage"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:background="@drawable/common_btn_bg"
|
||||
android:contentDescription="@string/empty"
|
||||
android:gravity="center"
|
||||
android:text="@string/send"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_image"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:src="@drawable/message_input_ic_image" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_camera"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="88dp"
|
||||
android:src="@drawable/message_input_ic_camera" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_gift"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginStart="88dp"
|
||||
android:src="@drawable/message_input_ic_gift" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.effective.android.panel.view.content.LinearContentContainer>
|
||||
|
||||
<!-- 面板区域,仅能包含PanelView-->
|
||||
<com.effective.android.panel.view.panel.PanelContainer
|
||||
android:id="@+id/panel_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- 每一项面板 -->
|
||||
<!-- panel_layout 用于指定面板该 ID 对应的布局 ,必须项-->
|
||||
<!-- panel_trigger 用于用户点击该 ID 对应的 View 时切换到该面板 -->
|
||||
<!-- panel_toggle 用于当该面板显示时 ,用户再次点击 panel_trigger 对应的 View 时是否回切输入法-->
|
||||
<com.effective.android.panel.view.panel.PanelView
|
||||
android:id="@+id/panel_emotion"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:panel_layout="@layout/nim_message_emoji_layout"
|
||||
app:panel_trigger="@id/emoji_button" />
|
||||
|
||||
<com.effective.android.panel.view.panel.PanelView
|
||||
android:id="@+id/panel_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:panel_layout="@layout/nim_message_photo_layout"
|
||||
app:panel_trigger="@id/iv_image" />
|
||||
|
||||
</com.effective.android.panel.view.panel.PanelContainer>
|
||||
|
||||
</com.effective.android.panel.view.PanelSwitchLayout>
|
@@ -13,6 +13,15 @@ import android.widget.TextView;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.mango.core.im.friend.IMFriendModel;
|
||||
import com.mango.core.manager.IMNetEaseManager;
|
||||
import com.mango.core.manager.RoomEvent;
|
||||
import com.mango.core.utils.SystemUidUtil;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.room_chat.event.ClickRootViewEvent;
|
||||
import com.mango.moshen.ui.im.avtivity.NewBaseMessageActivity;
|
||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.netease.nim.uikit.api.NimUIKit;
|
||||
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
|
||||
import com.netease.nim.uikit.api.model.main.OnlineStateChangeObserver;
|
||||
@@ -25,20 +34,6 @@ import com.netease.nimlib.sdk.Observer;
|
||||
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.ui.im.avtivity.NewBaseMessageActivity;
|
||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||
import com.mango.moshen.room_chat.event.ClickRootViewEvent;
|
||||
import com.mango.core.im.friend.IMFriendModel;
|
||||
import com.mango.core.initial.InitialModel;
|
||||
import com.mango.core.initial.bean.InitInfo;
|
||||
import com.mango.core.level.UserLevelVo;
|
||||
import com.mango.core.manager.IMNetEaseManager;
|
||||
import com.mango.core.manager.RoomEvent;
|
||||
import com.mango.core.user.UserModel;
|
||||
import com.mango.core.user.bean.UserInfo;
|
||||
import com.mango.core.utils.SystemUidUtil;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@@ -259,14 +254,11 @@ public class NimRoomP2PMessageActivity extends NewBaseMessageActivity {
|
||||
int id = json.getIntValue("id");
|
||||
if (id == 1) {
|
||||
// 正在输入
|
||||
// Toast.makeText(NimRoomP2PMessageActivity.this, "对方正在输入...", Toast.LENGTH_LONG).show();
|
||||
SingleToastUtil.showToastShort("对方正在输入...");
|
||||
} else {
|
||||
// Toast.makeText(NimP2PMessageActivity.this, "command: " + content, Toast.LENGTH_SHORT).show();
|
||||
SingleToastUtil.showToast("对方正在输入...");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,29 +273,12 @@ public class NimRoomP2PMessageActivity extends NewBaseMessageActivity {
|
||||
MessageFragment fragment = new MessageFragment();
|
||||
fragment.setArguments(arguments);
|
||||
fragment.setContainerId(R.id.message_fragment_container);
|
||||
|
||||
// 等级限制:官方小秘书 和 系统消息,不设置等级限制
|
||||
if (!SystemUidUtil.isSystemUid(sessionId)) {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (userInfo != null) {
|
||||
UserLevelVo userLevelVo = userInfo.getUserLevelVo();
|
||||
if (userLevelVo != null) {
|
||||
fragment.setCurrentLevel(userLevelVo.experLevelSeq);
|
||||
}
|
||||
}
|
||||
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
|
||||
if (initInfo != null) {
|
||||
fragment.setLimitLevel(initInfo.getPrivateChatLevelNo());
|
||||
fragment.setLimitLevel(initInfo.getPrivateChatRegisterDay());
|
||||
}
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initToolBar() {
|
||||
//ToolBarOptions options = new NimToolBarOptions();
|
||||
// setToolBar(R.id.toolbar, options);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user