diff --git a/android/libs/jmessage-android_v2.3.0.jar b/android/libs/jmessage-android_v2.3.0.jar deleted file mode 100644 index 36b20df..0000000 Binary files a/android/libs/jmessage-android_v2.3.0.jar and /dev/null differ diff --git a/android/libs/jmessage-android_v2.4.1.jar b/android/libs/jmessage-android_v2.4.1.jar new file mode 100755 index 0000000..dbe49b0 Binary files /dev/null and b/android/libs/jmessage-android_v2.4.1.jar differ diff --git a/android/src/io/jchat/android/Constant.java b/android/src/io/jchat/android/Constant.java index f80c2da..1770131 100644 --- a/android/src/io/jchat/android/Constant.java +++ b/android/src/io/jchat/android/Constant.java @@ -8,6 +8,10 @@ public class Constant { public static final String OLD_PWD = "oldPwd"; public static final String NEW_PWD = "newPwd"; public static final String APP_KEY = "appKey"; + + /** + * UserInfo + */ public static final String NICKNAME = "nickname"; public static final String GENDER = "gender"; public static final String AVATAR_THUMB_PATH = "avatarThumbPath"; @@ -20,9 +24,14 @@ public class Constant { public static final String IS_NO_DISTURB = "isNoDisturb"; public static final String IS_IN_BLACKLIST = "isInBlackList"; public static final String IS_FRIEND = "isFriend"; + + /** + * Conversation + */ public static final String TYPE_USER = "user"; public static final String TYPE_GROUP = "group"; public static final String TYPE_SINGLE = "single"; + public static final String TYPE_CHAT_ROOM = "chatroom"; public static final String ID = "id"; public static final String SERVER_ID = "serverMessageId"; public static final String MESSAGE_ID = "messageId"; @@ -38,6 +47,10 @@ public class Constant { public static final String LATEST_MESSAGE = "latestMessage"; public static final String UNREAD_COUNT = "unreadCount"; public static final String CONVERSATION_TYPE = "conversationType"; + + /** + * Message + */ public static final String TARGET = "target"; public static final String TYPE = "type"; static final String MESSAGE_TYPE = "messageType"; @@ -52,6 +65,7 @@ public class Constant { public static final String CUSTOM = "custom"; public static final String EXTRAS = "extras"; public static final String THUMB_PATH = "thumbPath"; + public static final String LOCAL_PATH = "localPath"; public static final String PATH = "path"; public static final String DURATION = "duration"; public static final String LONGITUDE = "longitude"; @@ -78,4 +92,12 @@ public class Constant { static final String RETRACT_MESSAGE = "retractedMessage"; static final String MESSAGE_ARRAY = "messageArray"; static final String PROGRESS = "progress"; + public static final String UNRECEIPT_COUNT = "unreceiptCount"; + /** + * ChatRoom + */ + public static final String ROOM_ID = "roomId"; + public static final String ROOM_IDS = "roomIds"; + public static final String ROOM_NAME = "roomName"; + public static final String MEMBER_COUNT = "memberCount"; } diff --git a/android/src/io/jchat/android/JMessageModule.java b/android/src/io/jchat/android/JMessageModule.java index 15110ba..23d050f 100644 --- a/android/src/io/jchat/android/JMessageModule.java +++ b/android/src/io/jchat/android/JMessageModule.java @@ -25,9 +25,12 @@ import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import cn.jpush.im.android.api.ChatRoomManager; import cn.jpush.im.android.api.ContactManager; import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.callback.CreateGroupCallback; @@ -43,6 +46,7 @@ import cn.jpush.im.android.api.callback.GetUserInfoListCallback; import cn.jpush.im.android.api.callback.IntegerCallback; import cn.jpush.im.android.api.callback.ProgressUpdateCallback; +import cn.jpush.im.android.api.callback.RequestCallback; import cn.jpush.im.android.api.content.CustomContent; import cn.jpush.im.android.api.content.FileContent; import cn.jpush.im.android.api.content.ImageContent; @@ -51,6 +55,7 @@ import cn.jpush.im.android.api.content.TextContent; import cn.jpush.im.android.api.content.VoiceContent; import cn.jpush.im.android.api.enums.ContentType; +import cn.jpush.im.android.api.event.ChatRoomMessageEvent; import cn.jpush.im.android.api.event.ContactNotifyEvent; import cn.jpush.im.android.api.event.ConversationRefreshEvent; import cn.jpush.im.android.api.event.LoginStateChangeEvent; @@ -58,6 +63,7 @@ import cn.jpush.im.android.api.event.MessageRetractEvent; import cn.jpush.im.android.api.event.NotificationClickEvent; import cn.jpush.im.android.api.event.OfflineMessageEvent; +import cn.jpush.im.android.api.model.ChatRoomInfo; import cn.jpush.im.android.api.model.Conversation; import cn.jpush.im.android.api.model.GroupInfo; import cn.jpush.im.android.api.model.Message; @@ -78,6 +84,7 @@ public class JMessageModule extends ReactContextBaseJavaModule { private static final String RETRACT_MESSAGE_EVENT = "JMessage.MessageRetract"; // 消息撤回事件 private static final String CONTACT_NOTIFY_EVENT = "JMessage.ContactNotify"; // 收到好友请求消息事件 private static final String UPLOAD_PROGRESS_EVENT = "JMessage.UploadProgress"; // 上传(图片,文件等)进度事件 + private static final String RECEIVE_CHAT_ROOM_MSG_EVENT = "JMessage.ReceiveChatRoomMsgEvent"; // 收到聊天室消息事件 private static final int ERR_CODE_PARAMETER = 1; private static final int ERR_CODE_CONVERSATION = 2; private static final int ERR_CODE_MESSAGE = 3; @@ -301,10 +308,11 @@ public void createSendMessage(ReadableMap map, Callback callback) { content = new ImageContent(new File(path)); } else if (type.equals(Constant.VOICE)) { String path = map.getString(Constant.PATH); - File file = new File(map.getString(path)); + File file = new File(path); MediaPlayer mediaPlayer = MediaPlayer.create(mContext, Uri.parse(path)); int duration = mediaPlayer.getDuration() / 1000; // Millisecond to second. - content = new VoiceContent(file, duration); + content = new VoiceContent(file, + duration); mediaPlayer.release(); } else if (type.equals(Constant.LOCATION)) { double latitude = map.getDouble(Constant.LATITUDE); @@ -315,6 +323,9 @@ public void createSendMessage(ReadableMap map, Callback callback) { } else { content = new CustomContent(); } + if (map.hasKey(Constant.EXTRAS)) { + content.setExtras(ResultUtils.fromMap(map.getMap(Constant.EXTRAS))); + } if (type.equals(Constant.CUSTOM)) { CustomContent customContent = new CustomContent(); customContent.setAllValues(ResultUtils.fromMap(map.getMap(Constant.CUSTOM_OBJECT))); @@ -334,7 +345,7 @@ public void createSendMessage(ReadableMap map, Callback callback) { public void sendMessage(ReadableMap map, final Callback success, final Callback fail) { try { Conversation conversation = mJMessageUtils.getConversation(map); - final Message message = conversation.getMessage(map.getInt(Constant.ID)); + final Message message = conversation.getMessage(Integer.parseInt(map.getString(Constant.ID))); if (map.hasKey(Constant.SENDING_OPTIONS)) { MessageSendingOptions options = new MessageSendingOptions(); ReadableMap optionMap = map.getMap(Constant.SENDING_OPTIONS); @@ -1119,9 +1130,12 @@ public void deleteConversation(ReadableMap map, final Callback success, final Ca String username = map.getString(Constant.USERNAME); String appKey = map.hasKey(Constant.APP_KEY) ? map.getString(Constant.APP_KEY) : ""; JMessageClient.deleteSingleConversation(username, appKey); - } else { + } else if (type.equals(Constant.TYPE_GROUP)) { long groupId = Long.parseLong(map.getString(Constant.GROUP_ID)); JMessageClient.deleteGroupConversation(groupId); + } else { + String roomId = map.getString(Constant.ROOM_ID); + JMessageClient.deleteChatRoomConversation(Long.parseLong(roomId)); } mJMessageUtils.handleCallback(0, "", success, fail); } catch (Exception e) { @@ -1382,7 +1396,7 @@ public void setConversationExtras(ReadableMap map, Callback success, Callback fa ReadableMap extraMap = map.getMap(Constant.EXTRAS); ReadableMapKeySetIterator iterator = extraMap.keySetIterator(); JsonObject jsonObject = new JsonObject(); - while(iterator.hasNextKey()) { + while (iterator.hasNextKey()) { String key = iterator.nextKey(); jsonObject.addProperty(key, extraMap.getString(key)); } @@ -1447,6 +1461,166 @@ public void gotResult(int status, String desc) { } } + /** + * 查询当前应用 AppKey 下的聊天室信息 + * + * @param param 包含起始位置,获取个数 + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void getChatRoomListByApp(ReadableMap param, final Callback success, final Callback fail) { + try { + int start = param.getInt("start"); + int count = param.getInt("count"); + ChatRoomManager.getChatRoomListByApp(start, count, new RequestCallback>() { + @Override + public void gotResult(int status, String desc, List chatRoomInfos) { + mJMessageUtils.handleCallbackWithArray(status, desc, success, fail, + ResultUtils.toJSArray(chatRoomInfos)); + } + }); + } catch (Exception e) { + e.printStackTrace(); + mJMessageUtils.handleError(fail, ERR_CODE_PARAMETER, ERR_MSG_PARAMETER); + } + } + + /** + * 获取当前用户所加入的所有聊天室信息 + * + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void getChatRoomListByUser(final Callback success, final Callback fail) { + ChatRoomManager.getChatRoomListByUser(new RequestCallback>() { + @Override + public void gotResult(int status, String desc, List list) { + mJMessageUtils.handleCallbackWithArray(status, desc, success, fail, ResultUtils.toJSArray(list)); + } + }); + } + + /** + * 查询指定 roomId 聊天室信息 + * @param map 包含待查询 roomId + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void getChatRoomInfos(ReadableMap map, final Callback success, final Callback fail) { + try { + ReadableArray array = map.getArray(Constant.ROOM_IDS); + Set idSet = new HashSet<>(); + for (int i=0; i < array.size() -1; i++) { + long id = Long.parseLong(array.getString(i)); + idSet.add(id); + } + ChatRoomManager.getChatRoomInfos(idSet, new RequestCallback>() { + @Override + public void gotResult(int status, String desc, List list) { + mJMessageUtils.handleCallbackWithArray(status, desc, success, fail, ResultUtils.toJSArray(list)); + } + }); + } catch (Exception e) { + e.printStackTrace(); + mJMessageUtils.handleError(fail, ERR_CODE_PARAMETER, ERR_MSG_PARAMETER); + } + } + + /** + * 获取聊天室拥有者 UserInfo + * @param map 包含聊天室 id + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void getChatRoomOwner(ReadableMap map, final Callback success, final Callback fail) { + try { + long id = Long.parseLong(map.getString(Constant.ROOM_ID)); + Set set = new HashSet<>(); + set.add(id); + ChatRoomManager.getChatRoomInfos(set, new RequestCallback>() { + @Override + public void gotResult(int status, String desc, List list) { + list.get(0).getOwnerInfo(new GetUserInfoCallback() { + @Override + public void gotResult(int status, String desc, UserInfo userInfo) { + mJMessageUtils.handleCallbackWithObject(status, desc, success, fail, ResultUtils.toJSObject(userInfo)); + } + }); + } + }); + } catch (Exception e) { + e.printStackTrace(); + mJMessageUtils.handleError(fail, ERR_CODE_PARAMETER, ERR_MSG_PARAMETER); + } + } + + /** + * 进入聊天室,进入后才能收到聊天室信息及发言 + * @param map 包含聊天室 id + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void enterChatRoom(ReadableMap map, final Callback success, final Callback fail) { + ChatRoomManager.enterChatRoom(Long.parseLong(map.getString(Constant.ROOM_ID)), new RequestCallback() { + @Override + public void gotResult(int status, String desc, Conversation conversation) { + mJMessageUtils.handleCallbackWithObject(status, desc, success, fail, ResultUtils.toJSObject(conversation)); + } + }); + } + + /** + * 离开聊天室 + * @param map 包含聊天室 id + * @param success 成功回调 + * @param fail 失败回调 + */ + @ReactMethod + public void leaveChatRoom(ReadableMap map, final Callback success, final Callback fail) { + ChatRoomManager.leaveChatRoom(Long.parseLong(map.getString(Constant.ROOM_ID)), new BasicCallback() { + @Override + public void gotResult(int i, String s) { + mJMessageUtils.handleCallback(i, s, success, fail); + } + }); + } + + /** + * 从本地获取用户的聊天室会话列表,没有则返回为空的列表 + * @param success 成功回调 + */ + @ReactMethod + public void getChatRoomConversationList(Callback success) { + List list = JMessageClient.getChatRoomConversationList(); + success.invoke(ResultUtils.toJSArray(list)); + } + + /** + * 删除聊天室会话,同时删除本地相关缓存文件。成功返回 true,失败返回 false + * @param roomId 聊天室 id + */ + @ReactMethod + public void deleteChatRoomConversation(String roomId, Callback success) { + success.invoke(JMessageClient.deleteChatRoomConversation(Long.parseLong(roomId))); + } + + /** + * 创建聊天室会话,如果本地已存在,则不会重新创建,直接返回该会话 + * @param roomId 聊天室 id + */ + @ReactMethod + public void createChatRoomConversation(String roomId, Callback success) { + Conversation conversation = Conversation.createChatRoomConversation(Long.parseLong(roomId)); + success.invoke(ResultUtils.toJSObject(conversation)); + } + + + public void onEvent(LoginStateChangeEvent event) { Log.d(TAG, "登录状态改变事件:event = " + event.toString()); WritableMap map = Arguments.createMap(); @@ -1576,4 +1750,15 @@ public void onComplete(int status, String desc, File file) { } } } + + /** + * 聊天室消息事件 + * @param event {@link ChatRoomMessageEvent} + */ + public void onEventMainThread(ChatRoomMessageEvent event) { + List list = event.getMessages(); + Log.d(TAG, "收到聊天室消息"); + getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(RECEIVE_MSG_EVENT, ResultUtils.toJSArray(list)); + } } diff --git a/android/src/io/jchat/android/utils/JMessageUtils.java b/android/src/io/jchat/android/utils/JMessageUtils.java index 2201fdd..012e994 100644 --- a/android/src/io/jchat/android/utils/JMessageUtils.java +++ b/android/src/io/jchat/android/utils/JMessageUtils.java @@ -44,17 +44,22 @@ public Conversation getConversation(ReadableMap map) { String appKey = ""; if (map.hasKey(Constant.APP_KEY)) { appKey = map.getString(Constant.APP_KEY); + conversation = Conversation.createSingleConversation(username, appKey); + } else { + conversation = Conversation.createSingleConversation(username); } - conversation = Conversation.createSingleConversation(username, appKey); - } else { + } else if (type.equals(Constant.TYPE_GROUP)) { String groupId = map.getString(Constant.GROUP_ID); conversation = Conversation.createGroupConversation(Long.parseLong(groupId)); + } else { + String roomId = map.getString(Constant.ROOM_ID); + conversation = Conversation.createChatRoomConversation(Long.parseLong(roomId)); } return conversation; } public void sendMessage(ReadableMap map, MessageContent content, - final Callback success, final Callback fail) { + final Callback success, final Callback fail) { if (map.hasKey(Constant.EXTRAS)) { content.setExtras(ResultUtils.fromMap(map.getMap(Constant.EXTRAS))); } diff --git a/android/src/io/jchat/android/utils/ResultUtils.java b/android/src/io/jchat/android/utils/ResultUtils.java index ff29337..5786bc4 100644 --- a/android/src/io/jchat/android/utils/ResultUtils.java +++ b/android/src/io/jchat/android/utils/ResultUtils.java @@ -2,9 +2,12 @@ +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.text.TextUtils; import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMapKeySetIterator; import com.facebook.react.bridge.WritableArray; @@ -16,12 +19,17 @@ import org.json.JSONException; import org.json.JSONObject; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import cn.jpush.im.android.api.JMessageClient; +import cn.jpush.im.android.api.callback.GetUserInfoCallback; import cn.jpush.im.android.api.content.CustomContent; import cn.jpush.im.android.api.content.EventNotificationContent; import cn.jpush.im.android.api.content.FileContent; @@ -32,6 +40,7 @@ import cn.jpush.im.android.api.content.VoiceContent; import cn.jpush.im.android.api.enums.ConversationType; import cn.jpush.im.android.api.enums.MessageDirect; +import cn.jpush.im.android.api.model.ChatRoomInfo; import cn.jpush.im.android.api.model.Conversation; import cn.jpush.im.android.api.model.GroupInfo; import cn.jpush.im.android.api.model.Message; @@ -103,7 +112,7 @@ public static WritableMap toJSObject(GroupInfo groupInfo) { WritableMap result = Arguments.createMap(); result.putString(Constant.TYPE, Constant.TYPE_GROUP); - result.putDouble(Constant.ID, groupInfo.getGroupID()); + result.putString(Constant.ID, String.valueOf(groupInfo.getGroupID())); result.putString(Constant.NAME, groupInfo.getGroupName()); result.putString(Constant.DESC, groupInfo.getGroupDescription()); result.putInt(Constant.LEVEL, groupInfo.getGroupLevel()); @@ -127,6 +136,8 @@ public static WritableMap toJSObject(Message msg) { result.putMap(Constant.TARGET, toJSObject((UserInfo) msg.getTargetInfo())); } else if (msg.getTargetType() == ConversationType.group) { result.putMap(Constant.TARGET, toJSObject((GroupInfo) msg.getTargetInfo())); + } else { + result.putMap(Constant.TARGET, toJSObject((ChatRoomInfo) msg.getTargetInfo())); } } else { @@ -140,7 +151,7 @@ public static WritableMap toJSObject(Message msg) { } result.putDouble(Constant.CREATE_TIME, msg.getCreateTime()); - + result.putInt(Constant.UNRECEIPT_COUNT, msg.getUnreceiptCnt()); switch (msg.getContentType()) { case text: result.putString(Constant.TYPE, Constant.TEXT); @@ -149,7 +160,22 @@ public static WritableMap toJSObject(Message msg) { case image: result.putString(Constant.TYPE, Constant.IMAGE); ImageContent imageContent = (ImageContent) content; - result.putString(Constant.THUMB_PATH, imageContent.getLocalThumbnailPath() + "." + imageContent.getFormat()); + // jmessage did not add file extension, so save to local. + File file = new File(imageContent.getLocalThumbnailPath() + ".png"); + FileOutputStream fos = new FileOutputStream(file); + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inJustDecodeBounds = false; + opts.inSampleSize = 1; + Bitmap bitmap = BitmapFactory.decodeFile(imageContent.getLocalThumbnailPath(), opts); + try { + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.flush(); + fos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + result.putString(Constant.THUMB_PATH, file.getAbsolutePath()); + result.putString(Constant.LOCAL_PATH, imageContent.getLocalPath()); break; case voice: result.putString(Constant.TYPE, Constant.VOICE); @@ -231,6 +257,9 @@ public static WritableMap toJSObject(Conversation conversation) { } else if (conversation.getType() == ConversationType.group) { GroupInfo targetInfo = (GroupInfo) conversation.getTargetInfo(); map.putMap(Constant.TARGET, toJSObject(targetInfo)); + } else { + ChatRoomInfo chatRoomInfo = (ChatRoomInfo) conversation.getTargetInfo(); + map.putMap(Constant.TARGET, toJSObject(chatRoomInfo)); } } catch (Exception e) { @@ -240,20 +269,40 @@ public static WritableMap toJSObject(Conversation conversation) { return map; } + public static WritableMap toJSObject(ChatRoomInfo chatRoomInfo) { + final WritableMap map = Arguments.createMap(); + try { + map.putString(Constant.ROOM_ID, String.valueOf(chatRoomInfo.getRoomID())); + map.putString(Constant.TYPE, Constant.TYPE_CHAT_ROOM); + map.putString(Constant.ROOM_NAME, chatRoomInfo.getName()); + map.putString(Constant.APP_KEY, chatRoomInfo.getAppkey()); + map.putInt(Constant.MAX_MEMBER_COUNT, chatRoomInfo.getMaxMemberCount()); + map.putString(Constant.DESCRIPTION, chatRoomInfo.getDescription()); + map.putInt(Constant.MEMBER_COUNT, chatRoomInfo.getTotalMemberCount()); + map.putInt(Constant.CREATE_TIME, chatRoomInfo.getCreateTime()); + } catch (Exception e) { + e.printStackTrace(); + } + return map; + } + public static WritableArray toJSArray(List list) { WritableArray array = Arguments.createArray(); - - for (Object object : list) { - if (object instanceof UserInfo) { - array.pushMap(toJSObject((UserInfo) object)); - } else if (object instanceof GroupInfo) { - array.pushMap(toJSObject((GroupInfo) object)); - } else if (object instanceof Message) { - array.pushMap(toJSObject((Message) object)); - } else if (object instanceof Conversation) { - array.pushMap(toJSObject((Conversation) object)); - } else { - array.pushString(object.toString()); + if (list != null) { + for (Object object : list) { + if (object instanceof UserInfo) { + array.pushMap(toJSObject((UserInfo) object)); + } else if (object instanceof GroupInfo) { + array.pushMap(toJSObject((GroupInfo) object)); + } else if (object instanceof Message) { + array.pushMap(toJSObject((Message) object)); + } else if (object instanceof Conversation) { + array.pushMap(toJSObject((Conversation) object)); + } else if (object instanceof ChatRoomInfo) { + array.pushMap(toJSObject((ChatRoomInfo) object)); + } else { + array.pushString(object.toString()); + } } } @@ -270,4 +319,5 @@ public static JSONObject toJSObject(String eventName, JSONObject value) { } return result; } + } diff --git a/document/API.md b/document/API.md index 4e7d345..70373e4 100644 --- a/document/API.md +++ b/document/API.md @@ -42,10 +42,28 @@ import JMessage from 'jmessage-react-plugin'; - [getConversation](#getconversation) - [getConversations](#getconversations) - [resetUnreadMessageCount](#resetunreadmessagecount) +- [聊天室](#聊天室) + - [getChatRoomListByApp](#getchatroomlistbyapp) + - [getChatRoomListByUser](#getchatroomlistbyuser) + - [getChatRoomInfos](#getchatroominfos) + - [getChatRoomOwner](#getchatroomowner) + - [enterChatRoom](#enterchatroom) + - [leaveChatRoom](#leavechatroom) + - [getChatRoomConversationList](#getchatroomconversationlist) +- [好友](#好友) + - [sendInvitationRequest](#sendinvitationrequest) + - [acceptInvitation](#acceptInvitation) + - [declineInvitation](#declineinvitation) + - [getFriends](#getfriends) + - [removeFromFriendList](#removefromfriendlist) + - [updateFriendNoteName](#updatefriendnotename) + - [updateFriendNoteText](#updatefriendnotetext) - [事件监听]() - [消息事件](#addreceivemessagelistener) - [addReceiveMessageListener](#addreceivemessagelistener) - [removeReceiveMessageListener](#addreceivemessagelistener) + - [*addReceiveChatRoomMsgListener]() + - [*removeReceiveChatRoomMsgListener]() - [离线消息](#addsyncofflinemessagelistener) - [addSyncOfflineMessageListener](#addsyncofflinemessagelistener) - [removeSyncOfflineMessageListener](#addsyncofflinemessagelistener) @@ -828,28 +846,14 @@ JMessage.enterConversation({ type: 'single', username: 'username', appKey: 'appK ### exitConversation -**(Android only)** 退出聊天会话。调用后,聊天会话之后的相关消息通知将会被触发。 +**(Android only)** 退出当前聊天会话。调用后,聊天会话之后的相关消息通知将会被触发。 #### 示例 ```js -JMessage.exitConversation({ type: 'single', username: 'username', appKey: 'appKey' }, - (conversation) => { - // do something. - - }, (error) => { - var code = error.code - var desc = error.description - ) +JMessage.exitConversation(); ``` -#### 参数说明 - -- type: 会话类型。可以为 'single' 或 'group'。 -- username: 对方用户的用户名。当 `type` 为 'single' 时,`username` 为必填。 -- appKey: 对方用户所属应用的 AppKey。如果不填,默认为当前应用。 -- groupId: 对象群组 id。当 `type` 为 'group' 时,`groupId` 为必填。 - ### getConversation 获取[聊天会话对象](./Models.md)。 @@ -898,7 +902,7 @@ JMessage.getConversations((conArr) => { // conArr: 会话数组。 ```js JMessage.resetUnreadMessageCount({ type: 'single', username: 'username', appKey: 'appKey' }, - (conversation) => { + (conversation) => { // do something. }, (error) => { @@ -915,6 +919,148 @@ JMessage.resetUnreadMessageCount({ type: 'single', username: 'username', appKey: - groupId: 对象群组 id。当 `type` 为 'group' 时,`groupId` 为必填。 +## 聊天室 + +### getChatRoomListByApp + +查询当前 AppKey 下的聊天室信息。 + +#### 示例 + +```js +JMessage.getChatRoomListByApp({ start: 0, count: 5, reason: '请求添加好友'}, + (chatRoomList) => { // chatRoomList 为所有聊天室信息 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +#### 参数说明 + +- start: 起始位置。 +- count: 获得个数。 + +### getChatRoomListByUser + +获取当前用户(登录用户)所加入的所有聊天室信息。 + +#### 示例 + +```js +JMessage.getChatRoomListByUser((chatRoomList) => { // chatRoomList 为当前用户加入的所有聊天室列表 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +### getChatRoomInfos + +查询指定 roomId 聊天室信息。 + +#### 示例 + +```js +JMessage.getChatRoomInfos({ roomIds: ['Example_RoomId_1','Example_RoomId_2']}, + (chatRoomList) => { // chatRoomList 为指定的聊天室列表 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +#### 参数说明 + +- roomIds:需要获取聊天室详情的聊天室 id 列表。 + +### getChatRoomOwner + +查询指定 roomId 聊天室的所有者。 + +#### 示例 + +```js +JMessage.getChatRoomOwner({ roomId: 'Example_RoomId_1'}, + (userInfo) => { // userInfo 为该聊天室的所有者 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +#### 参数说明 + +- roomId:需要获取聊天室所有者的聊天室 id。 + +### enterChatRoom + +进入聊天室,进入后才能收到聊天室信息及发言。 + +#### 示例 + +```js +JMessage.enterChatRoom({ roomId: 'Example_RoomId_1'}, + (conversation) => { // 进入聊天室,会自动创建并返回该聊天室会话信息。 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +#### 参数说明 + +- roomId:要进入的聊天室的 id。 + +### leaveChatRoom + +离开指定聊天室。 + +#### 示例 + +```js +JMessage.leaveChatRoom({ roomId: 'Example_RoomId_1'}, + () => { + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + +#### 参数说明 + +- roomId:要离开的聊天室的 id。 + +### getChatRoomConversationList + +从本地获取用户的聊天室会话列表,没有则返回为空的列表。 + +#### 示例 + +```js +JMessage.getChatRoomConversationList( (conversationList) => { // conversationList 为聊天室会话信息。 + // do something. + + }, (error) => { + var code = error.code + var desc = error.description + }) +``` + + + ## 好友 JMessage 好友模块仅实现对用户好友关系的托管,以及相关好友请求的发送与接收。 diff --git a/document/Models.md b/document/Models.md index ee33b52..8a9ca3e 100644 --- a/document/Models.md +++ b/document/Models.md @@ -2,6 +2,7 @@ - [UserInfo](#userinfo) - [GroupInfo](#groupinfo) +- [ChatRoomInfo](#chatroominfo) - [Conversation](#conversation) - [Message](#message) - [TextMessage](#textmessage) @@ -47,6 +48,22 @@ isNoDisturb: boolean, // 是否免打扰 isBlocked: boolean // 是否屏蔽群消息 ``` +## ChatRoomInfo + +```js +type: 'chatroom', +roomId: string, // 聊天室 id +roomName: string, // 聊天室名字 +appKey: string, // 聊天室所属 AppKey +owner: UserInfo, // 聊天室拥有者 +maxMemberCount: number, // 聊天室最大成员数量 +description: string, // 聊天室描述 +memberCount: number, // 聊天室当前成员数量 +createTime: number // 聊天室创建时间,单位 秒 +``` + + + ## Conversation - 单聊:如果用户有昵称,`title` 为昵称,否则为 username。 @@ -56,8 +73,8 @@ isBlocked: boolean // 是否屏蔽群消息 title: string, // 会话标题 latestMessage: Message, // 最近的一条消息对象 unreadCount: number, // 未读消息数 -conversationType: 'single' / 'group', -target: UserInfo / GroupInfo // 聊天对象信息 +conversationType: 'single' / 'group', / 'chatroom' +target: UserInfo / GroupInfo / ChatRoomInfo // 聊天对象信息 ``` ## Message @@ -87,6 +104,7 @@ from: UserInfo, // 消息发送者对象 target: UserInfo / GroupInfo, // 消息接收者对象 extras: object, // 附带的键值对 thumbPath: string // 图片的缩略图路径 +localPath: string // 图片本地路径 ``` ### VoiceMessage diff --git a/example/android/app/app.iml b/example/android/app/app.iml index 043df72..c5d0899 100644 --- a/example/android/app/app.iml +++ b/example/android/app/app.iml @@ -91,13 +91,11 @@ - - @@ -110,15 +108,15 @@ - + + - @@ -131,13 +129,13 @@ - + diff --git a/example/app/routes/Chat/index.js b/example/app/routes/Chat/index.js index c0ed63d..6c7c556 100644 --- a/example/app/routes/Chat/index.js +++ b/example/app/routes/Chat/index.js @@ -90,6 +90,13 @@ export default class Chat extends Component { auroraMsg.msgType = "video" } + if (jmessage.type === 'event') { + // auroraMsg.mediaPath = jmessage.path + // auroraMsg.duration = jmessage.duration + Alert.alert('event' , jmessage.eventType) + auroraMsg.text = jmessage.eventType + } + var user = { userId: "1", displayName: "", @@ -175,9 +182,12 @@ export default class Chat extends Component { if (this.conversation.conversationType === 'single') { parames.type = 'single' parames.username = this.conversation.key - } else { + } else if (this.conversation.conversationType === 'group') { parames.type = 'group' parames.groupId = this.conversation.key + } else { + parames.type = 'chatroom' + parames.roomId = this.conversation.key } this.messageListDidLoadCallback = () => { @@ -205,22 +215,29 @@ export default class Chat extends Component { Alert.alert('message.target.username', message.target.username) Alert.alert('this.conversation.key', this.conversation.key) } - } else { + } else if (this.conversation.conversationType === 'group') { if (message.target.type === 'group') { if (message.from.id === this.conversation.key) { var msg = this.convertJMessageToAuroraMsg(message) AuroraIController.appendMessages([msg]) } } + } else { + if (message.target.type === 'chatroom') { + if (message.target.roomId === this.conversation.key) { + var msg = this.convertJMessageToAuroraMsg(message) + AuroraIController.appendMessages([msg]) + } + } } } JMessage.addReceiveMessageListener(this.receiveMessageCallBack) } AuroraIController.addMessageListDidLoadListener(this.messageListDidLoadCallback) - this.timer = setTimeout(() => { - console.log("Sending custom message") - this.sendCustomMessage(); - }, 2000) + // this.timer = setTimeout(() => { + // console.log("Sending custom message") + // this.sendCustomMessage(); + // }, 2000) } onInputViewSizeChange = (size) => { @@ -228,7 +245,8 @@ export default class Chat extends Component { if (this.state.inputLayoutHeight != size.height) { this.setState({ inputLayoutHeight: size.height, - inputViewLayout: { width: size.width, height: size.height } + inputViewLayout: { width: size.width, height: size.height }, + messageListLayout: { flex: 1, width: window.width, margin: 0 } }) } } @@ -243,6 +261,9 @@ export default class Chat extends Component { resetMenu() { if (Platform.OS === "android") { this.refs["ChatInput"].showMenu(false) + this.setState({ + messageListLayout: { flex: 1, width: window.width, margin: 0 }, + }) } else { this.setState({ inputViewLayout: { width: window.width, height: 86 } @@ -264,8 +285,7 @@ export default class Chat extends Component { onTouchEditText = () => { console.log("scroll to bottom") - AuroraIController.scrollToBottom(true); - // this.refs["ChatInput"].showMenu(false) + this.refs["ChatInput"].showMenu(false) this.setState({ inputViewLayout: { width: window.width, height: this.state.inputLayoutHeight } }) @@ -275,19 +295,20 @@ export default class Chat extends Component { var navigationBar = 50 this.setState({ messageListLayout: { flex: 0, width: 0, height: 0 }, - inputViewLayout: { flex:1, width: window.width, height: window.height } + inputViewLayout: { flex: 1, width: window.width, height: window.height } }) } onRecoverScreen = () => { this.setState({ messageListLayout: { flex: 1, width: window.width, margin: 0 }, - inputViewLayout: { flex: 0, width: window.width, height: this.state.inputLayoutHeight} + inputViewLayout: { flex: 0, width: window.width, height: this.state.inputLayoutHeight } }) } onMsgClick = (message) => { console.log(message) + alert(JSON.stringify(message)) } onStatusViewClick = (message) => { @@ -343,6 +364,7 @@ export default class Chat extends Component { } onTakePicture = (mediaPath) => { + console.log("onTakePicture, path: " + mediaPath) var message = this.getNormalMessage() message.messageType = "image" message.path = mediaPath @@ -532,7 +554,7 @@ export default class Chat extends Component { onTouchEditText={this.onTouchEditText} onFullScreen={this.onFullScreen} onRecoverScreen={this.onRecoverScreen} - onSizeChanged={this.onInputViewSizeChange} + onSizeChange={this.onInputViewSizeChange} /> ); diff --git a/example/app/routes/Home/ConversationList/index.js b/example/app/routes/Home/ConversationList/index.js index 81870b5..f53f4e9 100644 --- a/example/app/routes/Home/ConversationList/index.js +++ b/example/app/routes/Home/ConversationList/index.js @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import ReactNative from 'react-native'; +import ReactNative, { ScrollView } from 'react-native'; import JMessage from 'jmessage-react-plugin'; import FormButton from '../../../views/FormButton' @@ -48,14 +48,17 @@ const styles = StyleSheet.create({ backgroundColor: 'rgba(0, 0, 0, 0.5)', }, modalContent: { - width: 200, - height: 150, - justifyContent: 'center', + width: 300, + height: 300, + justifyContent: 'space-between', alignItems: 'center', backgroundColor: '#ffffff', }, modalButton: { - + margin: 10, + }, + inputStyle: { + width: 200 } }); @@ -84,11 +87,11 @@ export default class ConversationList extends React.Component { tabBarIcon: ({ tintColor }) => ( - - ), + ), } }; @@ -119,6 +122,10 @@ export default class ConversationList extends React.Component { JMessage.setDebugMode({ enable: true }); + JMessage.addReceiveMessageListener((message) => { + //TODO sort conversation list or create conversation, send message to Chat. + + }) } componentWillMount() { this.reloadConversationList() @@ -231,16 +238,32 @@ export default class ConversationList extends React.Component { }) } + enterChatRoom(params) { + JMessage.enterChatRoom(params.roomId, (conversation) => { + var chatRoom = { + conversationType: 'chatroom', + key: conversation.roomId, + owner: conversation.owner, + totalMemberCount: conversation.totalMemberCount + } + this.props.navigation.navigate('Chat', { + conversation: chatRoom + }) + }, (error) => { + console.alert("error, code: " + error.code + ", description: " + error.description) + }) + } + render() { this.listView = ( - + - ) + ) } > - + return ( @@ -274,6 +297,7 @@ export default class ConversationList extends React.Component { { this.setState({ modalText: e }) }}> @@ -303,6 +327,22 @@ export default class ConversationList extends React.Component { }} style={styles.modalButton} title='创建群聊' /> +