@smart-link/rn-im 1.0.26 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/api/addressList.d.ts +16 -15
  2. package/dist/api/addressList.js +15 -1
  3. package/dist/api/user.js +1 -1
  4. package/dist/components/Camera/Camera.js +3 -2
  5. package/dist/components/Camera/CameraCapture.js +61 -12
  6. package/dist/components/ChatAvatar/ChatAvatar.d.ts +3 -3
  7. package/dist/components/ChatAvatar/ChatAvatar.js +51 -49
  8. package/dist/components/ChatAvatar/ChatAvatarId.d.ts +2 -2
  9. package/dist/components/ChatAvatar/ChatAvatarId.js +19 -46
  10. package/dist/components/ChatAvatar/ChatAvatarLocal.js +22 -9
  11. package/dist/components/Favicon.js +1 -1
  12. package/dist/components/LocalImage.js +3 -1
  13. package/dist/components/styles.d.ts +7 -1
  14. package/dist/components/styles.js +16 -11
  15. package/dist/hooks/useAnimatedValue.d.ts +2 -0
  16. package/dist/hooks/useAnimatedValue.js +9 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.js +1 -0
  19. package/dist/init.d.ts +2 -2
  20. package/dist/init.js +8 -5
  21. package/dist/interface.d.ts +9 -3
  22. package/dist/pages/address-list/AddressList.js +22 -40
  23. package/dist/pages/address-list/ChooseContact.js +209 -45
  24. package/dist/pages/address-list/MyGroups.d.ts +6 -0
  25. package/dist/pages/address-list/MyGroups.js +90 -0
  26. package/dist/pages/address-list/Organization.d.ts +0 -7
  27. package/dist/pages/address-list/Organization.js +24 -108
  28. package/dist/pages/address-list/UserDetail.js +5 -5
  29. package/dist/pages/address-list/UserSearch.js +6 -7
  30. package/dist/pages/address-list/addressList.routes.d.ts +9 -0
  31. package/dist/pages/address-list/addressList.routes.js +8 -0
  32. package/dist/pages/address-list/components/Icons.d.ts +8 -0
  33. package/dist/pages/address-list/components/Icons.js +15 -0
  34. package/dist/pages/address-list/components/OrgPath.d.ts +12 -0
  35. package/dist/pages/address-list/components/OrgPath.js +59 -0
  36. package/dist/pages/address-list/components/RenderUserItem.d.ts +9 -0
  37. package/dist/pages/address-list/components/RenderUserItem.js +14 -0
  38. package/dist/pages/address-list/{UserJobs.js → components/UserJobs.js} +2 -2
  39. package/dist/pages/address-list/useGroupCategory.d.ts +2 -0
  40. package/dist/pages/address-list/useGroupCategory.js +11 -0
  41. package/dist/pages/address-list/useRoleList.d.ts +2 -0
  42. package/dist/pages/address-list/useRoleList.js +11 -0
  43. package/dist/pages/collection/Collection.js +52 -8
  44. package/dist/pages/collection/ContentFactory.js +50 -3
  45. package/dist/pages/conversation/ForwardToConversation.js +4 -2
  46. package/dist/pages/conversation/List.js +15 -7
  47. package/dist/pages/conversation/components/ConversationCard.js +1 -7
  48. package/dist/pages/conversation/setting/GroupTransfer.js +9 -2
  49. package/dist/pages/conversation/setting/OptionAvatars.js +0 -1
  50. package/dist/pages/conversation/setting/OptionGroup.d.ts +1 -1
  51. package/dist/pages/conversation/setting/OptionGroup.js +4 -4
  52. package/dist/pages/conversation/setting/OptionGroupManage.js +4 -8
  53. package/dist/pages/conversation/setting/OptionGroupMoreMember.js +37 -18
  54. package/dist/pages/conversation/setting/Setting.js +20 -7
  55. package/dist/pages/conversation/setting/SettingChatBg.js +32 -16
  56. package/dist/pages/message/ChooseMember.js +9 -12
  57. package/dist/pages/message/FileSelector.js +40 -3
  58. package/dist/pages/message/MessageList.js +64 -30
  59. package/dist/pages/message/MessageRecord.js +1 -1
  60. package/dist/pages/message/components/MessageItem.d.ts +5 -6
  61. package/dist/pages/message/components/MessageItem.js +23 -15
  62. package/dist/pages/message/components/MessageOption.js +1 -0
  63. package/dist/pages/message/components/MessagePictureAlbum.js +6 -4
  64. package/dist/pages/message/components/Payload/PayloadFile.d.ts +1 -1
  65. package/dist/pages/message/components/Payload/PayloadFile.js +31 -13
  66. package/dist/pages/message/components/Payload/PayloadMultiple.js +3 -3
  67. package/dist/pages/message/components/Payload/PayloadNotify.js +17 -5
  68. package/dist/pages/message/components/Payload/PayloadPicture.js +6 -3
  69. package/dist/pages/message/components/Payload/PayloadText.js +7 -8
  70. package/dist/pages/message/components/Payload/PayloadVoice.js +7 -13
  71. package/dist/pages/message/components/Payload/PayloadWrapper.js +40 -19
  72. package/dist/pages/message/components/Payload/type.d.ts +1 -0
  73. package/dist/pages/message/components/TextMixMessage.d.ts +2 -0
  74. package/dist/pages/message/components/TextMixMessage.js +10 -3
  75. package/dist/pages/message/components/TextMixQuote.js +3 -3
  76. package/dist/pages/message/components/TextMixQuoteMessage.d.ts +2 -1
  77. package/dist/pages/message/components/TextMixQuoteMessage.js +2 -2
  78. package/dist/pages/message/components/UploadProgress.d.ts +1 -1
  79. package/dist/pages/message/components/UploadProgress.js +1 -1
  80. package/dist/pages/message/components/messageBar/EmojiPanel.d.ts +2 -2
  81. package/dist/pages/message/components/messageBar/EmojiPanel.js +29 -13
  82. package/dist/pages/message/components/messageBar/MessageBar.d.ts +1 -1
  83. package/dist/pages/message/components/messageBar/MessageBar.js +34 -20
  84. package/dist/pages/message/components/messageBar/MessageInput.d.ts +6 -7
  85. package/dist/pages/message/components/messageBar/MessageInput.js +21 -3
  86. package/dist/pages/message/components/messageBar/OptionPanel.d.ts +2 -3
  87. package/dist/pages/message/components/messageBar/OptionPanel.js +38 -18
  88. package/dist/pages/search/components/SearchUser.js +2 -2
  89. package/dist/pages/types.d.ts +2 -0
  90. package/dist/slice/contact/contact.slice.js +1 -0
  91. package/dist/utils/common-action-sheet.d.ts +1 -0
  92. package/dist/utils/common-action-sheet.js +18 -0
  93. package/dist/utils/event.d.ts +13 -0
  94. package/dist/utils/event.js +32 -0
  95. package/dist/utils/file-icon.js +29 -2
  96. package/dist/utils/file.d.ts +12 -1
  97. package/dist/utils/file.js +79 -25
  98. package/dist/utils/phone.d.ts +1 -1
  99. package/dist/utils/phone.js +1 -9
  100. package/dist/utils/request.d.ts +2 -1
  101. package/dist/utils/request.js +17 -6
  102. package/dist/utils/upload.d.ts +2 -4
  103. package/dist/utils/upload.js +13 -49
  104. package/package.json +5 -5
  105. package/dist/pages/address-list/Icons.d.ts +0 -5
  106. package/dist/pages/address-list/Icons.js +0 -9
  107. package/dist/utils/cookie.d.ts +0 -2
  108. package/dist/utils/cookie.js +0 -25
  109. package/dist/utils/file-operate.d.ts +0 -1
  110. package/dist/utils/file-operate.js +0 -3
  111. package/dist/utils/text-mix.d.ts +0 -9
  112. package/dist/utils/text-mix.js +0 -75
  113. /package/dist/pages/address-list/{CardInfo.d.ts → components/CardInfo.d.ts} +0 -0
  114. /package/dist/pages/address-list/{CardInfo.js → components/CardInfo.js} +0 -0
  115. /package/dist/pages/address-list/{UserJobs.d.ts → components/UserJobs.d.ts} +0 -0
@@ -1,27 +1,28 @@
1
1
  import { IUser } from '@smart-link/im-base';
2
+ import { IGroup, IRole } from "../interface";
2
3
  type IListTreeParams = {
3
- groupCatId: any;
4
- parentId: string;
5
- groupStatus: string;
6
- queryChild: boolean;
4
+ groupCatId?: any;
5
+ parentId?: string;
6
+ groupStatus?: string;
7
+ queryChild?: boolean;
7
8
  };
8
9
  type IListUserParams = {
9
- groupCategoryId: string;
10
- groupId: string;
11
- groupIdPathLike: string;
10
+ groupCategoryId?: string;
11
+ groupId?: string;
12
+ groupIdPathLike?: string;
12
13
  pageNum: number;
13
14
  pageSize: number;
14
- queryAll: boolean;
15
- userStatus: string;
15
+ queryAll?: boolean;
16
+ userStatus?: string;
16
17
  };
17
- export declare const listGroupCategory: (data: {
18
- appType: null;
19
- }) => Promise<import("../utils/request").IResponse<any>>;
20
- export declare const listTree: (data: IListTreeParams) => Promise<import("../utils/request").IResponse<any>>;
21
- export declare const listUser: (data: IListUserParams) => Promise<import("../utils/request").IResponse<any>>;
18
+ export declare const listGroupCategory: (data: any) => Promise<import("../utils/request").IResponse<any>>;
19
+ export declare const listTree: (data: IListTreeParams) => Promise<import("../utils/request").IResponse<IGroup[]>>;
20
+ export declare const listUser: (data: IListUserParams) => Promise<import("../utils/request").IResponse<IUser[]>>;
22
21
  export declare const queryUser: (userId: string) => Promise<import("../utils/request").IResponse<any>>;
22
+ export declare const queryUsersByCond: (userIds: string[]) => Promise<import("../utils/request").IResponse<IUser[]>>;
23
23
  export declare const searchUser: (params: {
24
24
  userNameLike: string;
25
- tenantId: string;
26
25
  }) => Promise<import("../utils/request").IResponse<IUser[]>>;
26
+ export declare const listRole: () => Promise<import("../utils/request").IResponse<IRole[]>>;
27
+ export declare const listRoleUser: (roleId: string) => Promise<import("../utils/request").IResponse<IUser[]>>;
27
28
  export {};
@@ -4,4 +4,18 @@ export const listGroupCategory = (data) => request.post(`${api}/open/groupQuery/
4
4
  export const listTree = (data) => request.post(`${api}/open/groupQuery/listTree`, data);
5
5
  export const listUser = (data) => request.post(`${api}/open/userQuery/listUser`, data);
6
6
  export const queryUser = (userId) => request.post(`${api}/open/userQuery/queryUsersByIds`, [userId]);
7
- export const searchUser = (params) => request.post(`${api}/open/userQuery/listUser`, Object.assign(Object.assign({}, params), { queryAll: true, userStatus: 'valid' }));
7
+ export const queryUsersByCond = (userIds) => request.post(`${api}/open/userQuery/queryUsersByCond`, {
8
+ userIds,
9
+ });
10
+ export const searchUser = (params) => request.post(`${api}/open/userQuery/listUser`, Object.assign(Object.assign({}, params), { queryAll: true, userStatus: 'valid', pageSize: 100, pageNum: 1 }));
11
+ export const listRole = () => request.post(`${api}/open/roleQuery/listRole`, {
12
+ pageNum: 1,
13
+ pageSize: 100,
14
+ roleStatus: "valid"
15
+ });
16
+ export const listRoleUser = (roleId) => request.post(`${api}/open/roleQuery/listRoleUser`, {
17
+ roleId,
18
+ pageNum: 1,
19
+ pageSize: 100,
20
+ userStatus: "valid"
21
+ });
package/dist/api/user.js CHANGED
@@ -2,5 +2,5 @@ import request from '../utils/request';
2
2
  export const userApi = '/api-user-center';
3
3
  export const searchUser = (params) => request.post(`${userApi}/open/userQuery/listUser`, Object.assign(Object.assign({}, params), { queryAll: true, userStatus: 'valid' }));
4
4
  export const updateUserInfo = (params) => request.post(`${userApi}/mgr/user/editUserInfo`, params);
5
- export const reloadUserInfo = () => request.post('/reloadUserInfo', {});
5
+ export const reloadUserInfo = () => request.post('/auth/reloadUserInfo', {});
6
6
  export const queryUserByIds = (userIds) => request.post(`${userApi}/open/userQuery/queryUsersByIds`, userIds);
@@ -11,7 +11,7 @@ import React, { memo } from 'react';
11
11
  import CameraResult from './CameraResult';
12
12
  import CameraCapture, { buildPictureData } from './CameraCapture';
13
13
  import { Modal, Platform, StatusBar, NativeModules } from "react-native";
14
- import { toAbsolutePath } from "../../utils/file";
14
+ import { toAbsolutePath, toFullPath } from "../../utils/file";
15
15
  import PhotoEditor from "@baronha/react-native-photo-editor";
16
16
  const Camera = memo(props => {
17
17
  const { horizontal = true, cancelCamera, finishTakePicture, finishTakeRecord, } = props;
@@ -31,7 +31,8 @@ const Camera = memo(props => {
31
31
  }
32
32
  else {
33
33
  try {
34
- const file = yield NativeModules.PictureEditingModule.editPicture(result.localPath);
34
+ console.log('editPicture', result.localPath, toFullPath(result.localPath));
35
+ const file = yield NativeModules.PictureEditingModule.editPicture(toFullPath(result.localPath));
35
36
  console.log(file.uri);
36
37
  file.path = file.uri;
37
38
  const fileInfo = yield buildPictureData(file);
@@ -8,13 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import React, { memo, useEffect, useState, useCallback, useRef } from 'react';
11
- import { StyleSheet, Text, TouchableOpacity, View, Animated, Dimensions } from 'react-native';
11
+ import { StyleSheet, Text, TouchableOpacity, View, Animated, Dimensions, Platform } from 'react-native';
12
12
  import { Camera, useCameraDevice, useCameraFormat, useMicrophonePermission } from 'react-native-vision-camera';
13
13
  import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
14
14
  import { numberToTime, ResourceType } from '@smart-link/im-base';
15
- import { moveFile, requestSaveFilePermissionIfAndroid, toAbsolutePath } from '../../utils/file';
15
+ import { moveFile, requestSaveFilePermissionIfAndroid, toFullPath } from '../../utils/file';
16
16
  import { getImManager } from '../../init';
17
- import { dp, CaihIcon } from '@smart-link/rn-ui';
17
+ import { dp, CaihIcon, Toast } from '@smart-link/rn-ui';
18
18
  import { createVideoThumbnail, Image, Video, getFileSize, uuidv4 } from 'react-native-compressor';
19
19
  const { PICTURE, VIDEO } = ResourceType;
20
20
  const FlashModeValue = ['on', 'off', 'auto'];
@@ -28,7 +28,8 @@ const CameraCapture = memo(props => {
28
28
  const camera = useRef(null);
29
29
  const [cameraTypeIndex, setCameraTypeIndex] = useState(0);
30
30
  const [isRecording, setIsRecording] = useState(false);
31
- const [flashModeIndex, setFlashModeIndex] = useState(2);
31
+ const [flashModeIndex, setFlashModeIndex] = useState(1);
32
+ const toast = useRef();
32
33
  const microphone = useMicrophonePermission();
33
34
  const device = useCameraDevice(CameraTypeValue[cameraTypeIndex]);
34
35
  const format = useCameraFormat(device, [
@@ -39,6 +40,7 @@ const CameraCapture = memo(props => {
39
40
  }
40
41
  ]);
41
42
  const takePicture = () => __awaiter(void 0, void 0, void 0, function* () {
43
+ var _a, _b;
42
44
  if (camera.current && !isRecording) {
43
45
  const success = yield requestSaveFilePermissionIfAndroid(getImManager());
44
46
  if (!success) {
@@ -46,10 +48,29 @@ const CameraCapture = memo(props => {
46
48
  }
47
49
  const photo = yield camera.current.takePhoto({
48
50
  flash: FlashModeValue[flashModeIndex],
51
+ enableShutterSound: false,
49
52
  });
50
53
  console.log('photo: ', photo);
51
- const pictureData = yield buildPictureData(photo);
52
- finishTakePicture && finishTakePicture(pictureData);
54
+ if (Platform.OS === 'android') {
55
+ toast.current = Toast.loading();
56
+ }
57
+ try {
58
+ const pictureData = yield buildPictureData(photo);
59
+ if (Platform.OS === 'android') {
60
+ (_a = toast.current) === null || _a === void 0 ? void 0 : _a.close();
61
+ toast.current = null;
62
+ }
63
+ finishTakePicture === null || finishTakePicture === void 0 ? void 0 : finishTakePicture(pictureData);
64
+ }
65
+ catch (e) {
66
+ console.log('take picture error: ', e);
67
+ }
68
+ finally {
69
+ if (Platform.OS === 'android') {
70
+ (_b = toast.current) === null || _b === void 0 ? void 0 : _b.close();
71
+ toast.current = null;
72
+ }
73
+ }
53
74
  }
54
75
  });
55
76
  const takeRecord = () => __awaiter(void 0, void 0, void 0, function* () {
@@ -63,9 +84,28 @@ const CameraCapture = memo(props => {
63
84
  videoCodec: 'h264',
64
85
  fileType: 'mp4',
65
86
  onRecordingFinished: (data) => __awaiter(void 0, void 0, void 0, function* () {
87
+ var _c, _d;
66
88
  console.log('onRecordingFinished: ', data);
67
- const videoData = yield buildVideoData(data);
68
- finishTakeRecord === null || finishTakeRecord === void 0 ? void 0 : finishTakeRecord(videoData);
89
+ if (Platform.OS === 'android') {
90
+ toast.current = Toast.loading();
91
+ }
92
+ try {
93
+ const videoData = yield buildVideoData(data);
94
+ if (Platform.OS === 'android') {
95
+ (_c = toast.current) === null || _c === void 0 ? void 0 : _c.close();
96
+ toast.current = null;
97
+ }
98
+ finishTakeRecord === null || finishTakeRecord === void 0 ? void 0 : finishTakeRecord(videoData);
99
+ }
100
+ catch (e) {
101
+ console.log('record error: ', e);
102
+ }
103
+ finally {
104
+ if (Platform.OS === 'android') {
105
+ (_d = toast.current) === null || _d === void 0 ? void 0 : _d.close();
106
+ toast.current = null;
107
+ }
108
+ }
69
109
  }),
70
110
  onRecordingError: (error) => {
71
111
  console.log('onRecordingError: ', error);
@@ -75,12 +115,14 @@ const CameraCapture = memo(props => {
75
115
  }
76
116
  });
77
117
  const stopRecord = () => {
78
- var _a;
118
+ var _a, _b;
79
119
  console.log('stopRecord: ', isRecording);
80
120
  if (isRecording) {
81
121
  (_a = camera.current) === null || _a === void 0 ? void 0 : _a.stopRecording();
82
122
  setIsRecording(false);
83
123
  }
124
+ (_b = toast.current) === null || _b === void 0 ? void 0 : _b.close();
125
+ toast.current = null;
84
126
  };
85
127
  const switchCameraType = useCallback(() => {
86
128
  const index = (cameraTypeIndex + 1) % 2;
@@ -98,6 +140,13 @@ const CameraCapture = memo(props => {
98
140
  }
99
141
  cancelCamera && cancelCamera();
100
142
  };
143
+ useEffect(() => {
144
+ return () => {
145
+ var _a;
146
+ (_a = toast.current) === null || _a === void 0 ? void 0 : _a.close();
147
+ toast.current = null;
148
+ };
149
+ }, []);
101
150
  return (<View style={styles.camera}>
102
151
  {device ? (<Camera ref={camera} device={device} format={format} isActive={true} style={styles.preview} photo={true} video={true} audio={microphone.hasPermission} outputOrientation="portrait" onInitialized={() => {
103
152
  console.log('Camera initialized!');
@@ -273,7 +322,7 @@ export function buildPictureData(data) {
273
322
  compressionMethod: 'auto'
274
323
  });
275
324
  const localPath = yield moveFile(tmp, filename, PICTURE);
276
- const size = yield getFileSize(localPath);
325
+ const size = yield getFileSize(toFullPath(localPath));
277
326
  let width = data.width;
278
327
  let height = data.height;
279
328
  if (data.orientation === 'portrait') {
@@ -297,14 +346,14 @@ function buildVideoData(data) {
297
346
  const uid = uuidv4();
298
347
  const path = data.path;
299
348
  try {
300
- const compressPath = yield Video.compress(toAbsolutePath(path), {
349
+ const compressPath = yield Video.compress(path, {
301
350
  compressionMethod: 'auto',
302
351
  maxSize: 1080,
303
352
  });
304
353
  const ext = compressPath.split('.').pop();
305
354
  const filename = VIDEO + '_' + uid + '.' + ext;
306
355
  const size = yield getFileSize(compressPath);
307
- let thumb = yield createVideoThumbnail(toAbsolutePath(compressPath));
356
+ let thumb = yield createVideoThumbnail(compressPath);
308
357
  console.log('RNThumbnail', thumb);
309
358
  const imageName = 'thumb_' + uid + '.jpg';
310
359
  const imagePath = yield moveFile(thumb.path, imageName, VIDEO);
@@ -1,15 +1,15 @@
1
1
  import React from 'react';
2
2
  import { ConversationType } from '@smart-link/im-base';
3
- import { ChatAvatarIdProps } from "./ChatAvatarId";
4
3
  type ChatAvatarProps = {
5
4
  id: string;
6
5
  name: string;
7
6
  url?: string;
8
7
  type?: ConversationType;
9
8
  size?: number;
9
+ needUpdate?: boolean;
10
10
  disabled?: boolean;
11
11
  editable?: boolean;
12
12
  onUpdate?: (url: string) => void;
13
- } & Pick<ChatAvatarIdProps, 'priority'>;
14
- declare const _default: React.MemoExoticComponent<({ id, name, url: fileId, size, disabled, type, editable, onUpdate, priority }: ChatAvatarProps) => React.JSX.Element>;
13
+ };
14
+ declare const _default: React.MemoExoticComponent<({ id, name, url: fileId, size, disabled, type, needUpdate, editable, onUpdate, }: ChatAvatarProps) => React.JSX.Element>;
15
15
  export default _default;
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { Avatar, dp, useNavigation } from '@smart-link/rn-ui';
10
+ import { Avatar, dp, Toast, useNavigation } from '@smart-link/rn-ui';
11
11
  import React, { memo } from 'react';
12
12
  import { Image, TouchableOpacity } from 'react-native';
13
13
  import ImagePicker from 'react-native-image-crop-picker';
@@ -15,77 +15,79 @@ import { getImManager } from '../../init';
15
15
  import { ConversationActions, ConversationType, updateGroupInfo } from '@smart-link/im-base';
16
16
  import { defaultAvatars } from '../../default-assets';
17
17
  import uploadFile from '../../utils/upload';
18
- import { updateUserInfo } from '../../api/user';
19
- import { useAuth } from '../../hooks/useImSelector';
18
+ import { reloadUserInfo, updateUserInfo } from '../../api/user';
20
19
  import { moveFile } from "../../utils/file";
21
20
  import ChatAvatarId from "./ChatAvatarId";
22
21
  import useImReady from "../../hooks/useImReady";
23
- const ChatAvatar = ({ id, name, url: fileId, size = dp(40), disabled, type = ConversationType.C2C, editable, onUpdate, priority = 'cache' }) => {
24
- const { user } = useAuth();
22
+ import { uuidv4 } from "react-native-compressor";
23
+ import useTranslation from "../../hooks/useTranslation";
24
+ import to from "await-to-js";
25
+ const ChatAvatar = ({ id, name, url: fileId, size = dp(40), disabled, type = ConversationType.C2C, needUpdate, editable, onUpdate, }) => {
25
26
  const navigation = useNavigation();
26
27
  const ready = useImReady();
28
+ const { t } = useTranslation();
27
29
  const defaultAvatar = {
28
30
  [ConversationType.C2C]: defaultAvatars.EMPTY,
29
31
  [ConversationType.C2G]: defaultAvatars.GROUP,
30
32
  [ConversationType.B2C]: defaultAvatars.BUSI_NOTIFY,
31
33
  }[type] || defaultAvatars.EMPTY;
32
- const onLongPress = () => __awaiter(void 0, void 0, void 0, function* () {
34
+ const onPress = () => __awaiter(void 0, void 0, void 0, function* () {
35
+ if (disabled)
36
+ return;
33
37
  if (editable) {
34
38
  const imManager = getImManager();
35
- let image;
36
- try {
37
- image = yield ImagePicker.openPicker({
38
- cropping: true,
39
- width: 300,
40
- height: 300,
41
- compressImageQuality: 0.7,
42
- });
43
- }
44
- catch (e) {
45
- console.log('pick cancel: ', e);
39
+ imManager.setNetwork(false);
40
+ const [err, image] = yield to(ImagePicker.openPicker({
41
+ cropping: true,
42
+ width: 300,
43
+ height: 300,
44
+ compressImageQuality: 0.7,
45
+ }));
46
+ imManager.setNetwork(true);
47
+ if (err) {
48
+ console.log('pick cancel: ', err);
46
49
  return;
47
50
  }
48
- console.log('pick: ', image);
49
- const fileId = yield uploadFile(image.path, image.mime);
50
- const localPath = yield moveFile(image.path, fileId + '.jpg', 'avatars');
51
- console.log('upload: ', fileId);
52
- if (type === ConversationType.C2C) {
53
- imManager.user.avatars = fileId;
54
- // 更新头像b
55
- setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
56
- try {
57
- yield updateUserInfo(Object.assign(Object.assign({}, user), { avatars: fileId }));
58
- }
59
- catch (e) {
60
- console.log('updateUserInfo error: ', e);
61
- }
62
- }), 0);
51
+ try {
52
+ const localPath = yield moveFile(image.path, uuidv4() + '.jpg', 'avatars');
53
+ const newFileId = yield uploadFile(localPath, image.mime);
54
+ if (type === ConversationType.C2C) {
55
+ imManager.user.avatars = newFileId;
56
+ const user = imManager.user;
57
+ yield updateUserInfo({
58
+ userId: user.userId,
59
+ userName: user.userName,
60
+ avatars: newFileId,
61
+ mobile: user.mobile,
62
+ });
63
+ yield reloadUserInfo();
64
+ }
65
+ else {
66
+ // 更新群头像
67
+ yield updateGroupInfo({
68
+ chatGroupId: id,
69
+ avatars: newFileId,
70
+ });
71
+ }
72
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(newFileId);
73
+ yield imManager.store.dispatch(ConversationActions.updateAvatars(imManager, id, newFileId));
63
74
  }
64
- else {
65
- // 更新群头像
66
- yield updateGroupInfo({
67
- chatGroupId: id,
68
- avatars: fileId,
69
- });
75
+ catch (e) {
76
+ console.log('[ChatAvatar] update avatar error: ', e);
77
+ Toast.error(t('avatarsUpdateFail'));
70
78
  }
71
- // 更新本地资源
72
- imManager.updateResource({ url: fileId, localPath });
73
- imManager.store.dispatch(ConversationActions.updateAvatars(imManager, id, fileId));
74
- onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(fileId);
75
- }
76
- });
77
- const onPress = () => {
78
- if (disabled || editable)
79
79
  return;
80
+ }
80
81
  if (type === ConversationType.C2C) {
81
82
  // 跳转到个人详情页
82
83
  navigation.navigate('UserDetail', {
83
84
  userId: id,
84
85
  });
85
86
  }
86
- };
87
- return (<TouchableOpacity style={{ width: size, height: size }} disabled={disabled} onPress={onPress} onLongPress={onLongPress}>
88
- {ready ? <ChatAvatarId priority={priority} id={id} fileId={fileId} size={size} name={name} defaultAvatar={defaultAvatar}/> : <Avatar icon={<Image style={size ? { width: size, height: size } : {}} source={defaultAvatar}/>}/>}
87
+ });
88
+ return (<TouchableOpacity style={{ width: size, height: size }} disabled={disabled} onPress={onPress}>
89
+ {ready ? <ChatAvatarId needUpdate={needUpdate} id={id} fileId={fileId} size={size} name={name} defaultAvatar={defaultAvatar}/> :
90
+ <Avatar icon={<Image style={size ? { width: size, height: size } : {}} source={defaultAvatar}/>}/>}
89
91
  </TouchableOpacity>);
90
92
  };
91
93
  export default memo(ChatAvatar);
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { ChatAvatarProps } from "./ChatAvatarLocal";
3
3
  export interface ChatAvatarIdProps extends ChatAvatarProps {
4
4
  id: string;
5
- priority?: 'cache' | 'outside';
5
+ needUpdate?: boolean;
6
6
  }
7
- declare const _default: React.MemoExoticComponent<({ id, fileId: fileIdProp, priority, ...ret }: ChatAvatarIdProps) => React.JSX.Element>;
7
+ declare const _default: React.MemoExoticComponent<({ id, fileId: fileIdProp, needUpdate, ...ret }: ChatAvatarIdProps) => React.JSX.Element>;
8
8
  export default _default;
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  var __rest = (this && this.__rest) || function (s, e) {
11
2
  var t = {};
12
3
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -19,49 +10,31 @@ var __rest = (this && this.__rest) || function (s, e) {
19
10
  return t;
20
11
  };
21
12
  import * as React from 'react';
22
- import { memo, useEffect, useState } from "react";
23
- import { getImManager } from "../../init";
13
+ import { memo, useEffect, useState } from 'react';
24
14
  import ChatAvatarLocal from "./ChatAvatarLocal";
25
- import { queryUserByIds } from "../../api/user";
26
- import { useAvatars } from "../../hooks/useImSelector";
15
+ import { getImManager } from "../../init";
16
+ import { AvatarSubscribe } from '@smart-link/im-base';
27
17
  const ChatAvatarId = (_a) => {
28
- var { id, fileId: fileIdProp, priority } = _a, ret = __rest(_a, ["id", "fileId", "priority"]);
29
- const [fileId, setFileId] = useState(fileIdProp);
30
- const cacheFileId = useAvatars()[id];
18
+ var { id, fileId: fileIdProp, needUpdate } = _a, ret = __rest(_a, ["id", "fileId", "needUpdate"]);
19
+ const [fileId, setFileId] = useState(fileIdProp || '');
31
20
  useEffect(() => {
32
- if (priority === 'outside') {
21
+ if (fileIdProp) {
33
22
  setFileId(fileIdProp);
34
- getImManager().updateAvatar({ avatarsId: id, url: fileIdProp });
35
- return;
36
- }
37
- if (priority === 'cache' && cacheFileId) {
38
- setFileId(cacheFileId);
39
- return;
23
+ if (needUpdate) {
24
+ getImManager().updateAvatar({ avatarsId: id, url: fileIdProp }).then(r => { });
25
+ }
40
26
  }
41
- getImManager().loadAvatarFromCache(id).then((localId) => __awaiter(void 0, void 0, void 0, function* () {
42
- if (!localId) {
43
- try {
44
- // 通过接口请求头像
45
- const { data: [user] } = yield queryUserByIds([id]);
46
- if (user === null || user === void 0 ? void 0 : user.avatars) {
47
- if (fileId !== user.avatars) {
48
- setFileId(user.avatars);
49
- getImManager().updateAvatar({ avatarsId: id, url: user.avatars });
50
- }
51
- }
52
- else {
53
- setFileId('');
54
- }
27
+ else {
28
+ getImManager().loadAvatarFromCache(id).then(fileId => {
29
+ if (fileId) {
30
+ setFileId(fileId);
55
31
  }
56
- catch (e) {
57
- console.log('queryUserByIds error: ', e);
58
- }
59
- }
60
- else {
61
- setFileId(localId);
62
- }
63
- }));
64
- }, [id, priority, fileIdProp, cacheFileId]);
32
+ });
33
+ }
34
+ return AvatarSubscribe.subscribe(id, (fileId) => {
35
+ setFileId(fileId);
36
+ });
37
+ }, [id, needUpdate, fileIdProp]);
65
38
  return (<ChatAvatarLocal fileId={fileId} {...ret}/>);
66
39
  };
67
40
  export default memo(ChatAvatarId);
@@ -14,6 +14,7 @@ import { useEffect, useState } from "react";
14
14
  import { getImManager } from "../../init";
15
15
  import RNFS from "react-native-fs";
16
16
  import LocalImage from "../../components/LocalImage";
17
+ import { toAbsolutePath } from "../../utils/file";
17
18
  // 防止重复下载
18
19
  const downloadMap = Object.create(null);
19
20
  const cacheMap = Object.create(null);
@@ -26,12 +27,24 @@ const ChatAvatarLocal = ({ fileId, size, name, defaultAvatar }) => {
26
27
  setReady(true);
27
28
  return;
28
29
  }
30
+ const fetchFromCache = (fileId) => __awaiter(void 0, void 0, void 0, function* () {
31
+ return new Promise((resolve, reject) => {
32
+ setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
33
+ if (cacheMap[fileId]) {
34
+ setAvatar(cacheMap[fileId]);
35
+ resolve(cacheMap[fileId]);
36
+ }
37
+ else {
38
+ yield fetchFromCache(fileId);
39
+ }
40
+ }), 16);
41
+ });
42
+ });
29
43
  if (fileId) {
30
44
  const imManager = getImManager();
31
45
  const localPath = yield imManager.loadResourceFromCache(fileId);
32
- // console.log('loadResourceFromCache: ', localPath)
33
46
  if (localPath) {
34
- const exists = yield RNFS.exists(localPath);
47
+ const exists = yield RNFS.exists(toAbsolutePath(localPath));
35
48
  if (exists) {
36
49
  cacheMap[fileId] = localPath;
37
50
  setAvatar(localPath);
@@ -39,13 +52,14 @@ const ChatAvatarLocal = ({ fileId, size, name, defaultAvatar }) => {
39
52
  return;
40
53
  }
41
54
  }
42
- if (downloadMap[fileId]) {
43
- return;
44
- }
45
- downloadMap[fileId] = true;
46
55
  try {
47
- console.log('imManager.download: ', fileId, Number.isNaN(Number(fileId)));
48
56
  if (Number.isNaN(Number(fileId))) {
57
+ if (downloadMap[fileId]) {
58
+ // 等待下载完成,从缓存获取
59
+ yield fetchFromCache(fileId);
60
+ return;
61
+ }
62
+ downloadMap[fileId] = true;
49
63
  // 下载头像文件
50
64
  const localPath = yield imManager.download({
51
65
  fileId,
@@ -67,8 +81,7 @@ const ChatAvatarLocal = ({ fileId, size, name, defaultAvatar }) => {
67
81
  setReady(true);
68
82
  }
69
83
  }
70
- catch (e) {
71
- downloadMap[fileId] = false;
84
+ finally {
72
85
  }
73
86
  }
74
87
  else {
@@ -15,7 +15,7 @@ const Favicon = ({ url, size = 40 }) => {
15
15
  if (!url)
16
16
  return;
17
17
  getFavicon(url).then((favicon) => {
18
- console.log('favicon: ', favicon);
18
+ // console.log('favicon: ', favicon);
19
19
  setFavicon(favicon);
20
20
  });
21
21
  }, [url]);
@@ -7,6 +7,8 @@ const LocalImage = memo(props => {
7
7
  if (Object.prototype.toString.call(localPath) === '[object String]') {
8
8
  source = { uri: toAbsolutePath(localPath) };
9
9
  }
10
- return <Image style={style} resizeMode={resizeMode} source={source}/>;
10
+ return <Image style={style} resizeMode={resizeMode} source={source} onError={(e) => {
11
+ console.log('local image error: ', localPath);
12
+ }}/>;
11
13
  });
12
14
  export default LocalImage;
@@ -6,8 +6,14 @@ export declare const shadowStyle: {
6
6
  };
7
7
  shadowRadius: number;
8
8
  shadowOpacity: number;
9
+ elevation?: undefined;
10
+ } | {
9
11
  elevation: number;
10
- };
12
+ shadowColor?: undefined;
13
+ shadowOffset?: undefined;
14
+ shadowRadius?: undefined;
15
+ shadowOpacity?: undefined;
16
+ } | undefined;
11
17
  export declare const borderStyle: {
12
18
  borderRadius: number;
13
19
  };
@@ -1,20 +1,25 @@
1
1
  import { dp } from '@smart-link/rn-ui';
2
- export const shadowStyle = {
3
- shadowColor: 'rgba(0, 0, 0, 0.08)',
4
- shadowOffset: {
5
- width: 0,
6
- height: dp(3),
2
+ import { Platform } from "react-native";
3
+ export const shadowStyle = Platform.select({
4
+ ios: {
5
+ shadowColor: '#eee',
6
+ shadowOffset: {
7
+ width: 0,
8
+ height: dp(2),
9
+ },
10
+ shadowRadius: dp(3),
11
+ shadowOpacity: 1,
7
12
  },
8
- shadowRadius: dp(3),
9
- shadowOpacity: 1,
10
- elevation: 1.5,
11
- };
13
+ android: {
14
+ elevation: 2,
15
+ },
16
+ });
12
17
  export const borderStyle = {
13
18
  borderRadius: dp(5),
14
19
  };
15
20
  export const plain = {
16
- color: '#000',
17
- fontSize: dp(14),
21
+ color: '#222',
22
+ fontSize: dp(15),
18
23
  paddingHorizontal: dp(12),
19
24
  paddingVertical: dp(10),
20
25
  };
@@ -0,0 +1,2 @@
1
+ import { Animated } from "react-native";
2
+ export declare function useAnimatedValue(initialValue: number): Animated.Value;
@@ -0,0 +1,9 @@
1
+ import { Animated } from "react-native";
2
+ import React from "react";
3
+ export function useAnimatedValue(initialValue) {
4
+ const value = React.useRef();
5
+ if (!value.current) {
6
+ value.current = new Animated.Value(initialValue);
7
+ }
8
+ return value.current;
9
+ }