@smart-link/rn-im 1.0.21 → 1.0.23

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.
@@ -14,7 +14,7 @@ exports.defaultAvatars = {
14
14
  exports.receiptStatus = {
15
15
  [im_base_1.MessageStatus.READ]: require('../assets/hook-blue-double.png'),
16
16
  [im_base_1.MessageStatus.ARRIVED]: require('../assets/hook-black-double.png'),
17
- [im_base_1.MessageStatus.EMITTED]: require('../assets/hook-black-double.png'),
17
+ [im_base_1.MessageStatus.EMITTED]: require('../assets/hook-black.png'),
18
18
  };
19
19
  exports.messageBackupImg = {
20
20
  cloud: require('../assets/cloud-backup.png'),
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.useDownloadImgSource = void 0;
13
13
  const react_1 = require("react");
14
14
  const init_1 = require("../init");
15
- function useDownload({ fileId, localPath, filename }) {
15
+ function useDownload({ fileId, localPath, filename, resourceType }) {
16
16
  const [local, setLocal] = (0, react_1.useState)(localPath);
17
17
  (0, react_1.useEffect)(() => {
18
18
  let cancel = false;
@@ -27,7 +27,7 @@ function useDownload({ fileId, localPath, filename }) {
27
27
  const file = yield imManager.download({
28
28
  fileId,
29
29
  filename: filename || fileId,
30
- resourceType: 'file',
30
+ resourceType,
31
31
  });
32
32
  yield imManager.updateResource({
33
33
  url: fileId,
@@ -35,7 +35,6 @@ const MaterialIcons_1 = __importDefault(require("react-native-vector-icons/Mater
35
35
  const ChatAvatar_1 = __importDefault(require("../../../components/ChatAvatar/ChatAvatar"));
36
36
  const useFormatMsgTime_1 = __importDefault(require("../../../hooks/useFormatMsgTime"));
37
37
  const useTranslation_1 = __importDefault(require("../../../hooks/useTranslation"));
38
- const init_1 = require("../../../init");
39
38
  const ConversationCard = (0, react_1.memo)(props => {
40
39
  const { status, selected, conversation, onPressCard, onLongPressCard } = props;
41
40
  const { t } = (0, useTranslation_1.default)();
@@ -46,12 +45,12 @@ const ConversationCard = (0, react_1.memo)(props => {
46
45
  const content = (0, im_base_1.getConversationContent)(text, errorText, draftText, tipsList, countText, t);
47
46
  const contentStyles = content.tips ? styles.contentRedStyles : null;
48
47
  const formatTime = (0, useFormatMsgTime_1.default)(time, true);
49
- const imManager = (0, init_1.getImManager)();
50
- // 还没找到为啥会让空的头像的人变成登录人的头像,先解决表面问题
51
- let newAvatars = avatars;
52
- if (avatars === imManager.user.avatars && name !== imManager.user.userName) {
53
- newAvatars = "";
54
- }
48
+ // const imManager = getImManager();
49
+ // // 还没找到为啥会让空的头像的人变成登录人的头像,先解决表面问题
50
+ // let newAvatars = avatars;
51
+ // if (avatars === imManager.user.avatars && name !== imManager.user.userName) {
52
+ // newAvatars = "";
53
+ // }
55
54
  return (<react_native_1.TouchableOpacity activeOpacity={0.5} style={[styles.card, enableTopStyles, selected && styles.selected]} onPress={() => {
56
55
  onPressCard && onPressCard(conversation);
57
56
  }} onLongPress={({ nativeEvent }) => {
@@ -59,7 +58,7 @@ const ConversationCard = (0, react_1.memo)(props => {
59
58
  }}>
60
59
  <react_native_1.View style={{ height: (0, rn_ui_1.dp)(50), width: (0, rn_ui_1.dp)(50), marginRight: (0, rn_ui_1.dp)(16) }}>
61
60
  <rn_ui_1.Badge text={unreadCount} dot={showPoint}>
62
- <ChatAvatar_1.default disabled type={type} id={id} size={(0, rn_ui_1.dp)(48)} name={name} url={newAvatars}/>
61
+ <ChatAvatar_1.default disabled type={type} id={id} size={(0, rn_ui_1.dp)(48)} name={name} url={avatars}/>
63
62
  </rn_ui_1.Badge>
64
63
  {status === 'online' && <react_native_1.View style={styles.status}>
65
64
  <MaterialIcons_1.default size={(0, rn_ui_1.dp)(14)} color={status === 'online' ? '#4caf50' : '#616161'} name={status === 'online' ? 'check-circle' : 'not-interested'}/>
@@ -48,7 +48,7 @@ const MessageList = ({ navigation }) => {
48
48
  const { t } = (0, useTranslation_1.default)();
49
49
  const messageListRef = (0, react_1.useRef)(null);
50
50
  const { currentConversation } = (0, useImSelector_1.useConversation)();
51
- const { messages, rangeList, quote, tips, isMultiple, multipleSelect } = (0, useImSelector_1.useMessage)();
51
+ const { messages, rangeList, quote, tips, isMultiple, multipleSelect, isSearch } = (0, useImSelector_1.useMessage)();
52
52
  const { user } = (0, useImSelector_1.useAuth)();
53
53
  const bar = (0, react_1.useRef)(null);
54
54
  const [showAlbum, setShowAlbum] = (0, react_1.useState)(false);
@@ -85,10 +85,11 @@ const MessageList = ({ navigation }) => {
85
85
  imManager.store.dispatch(im_base_1.MessagePanelActions.cancelMultipleSelect());
86
86
  }
87
87
  else {
88
- console.log('[离开会话]: ');
89
- imManager.store.dispatch(im_base_1.MessagePanelActions.saveDraftText(imManager));
90
88
  react_native_1.InteractionManager.runAfterInteractions(() => {
89
+ console.log('[离开会话]: ');
90
+ imManager.store.dispatch(im_base_1.MessagePanelActions.saveDraftText(imManager));
91
91
  imManager.leaveConversation();
92
+ imManager.store.dispatch(im_base_1.MessageActions.resetState());
92
93
  });
93
94
  }
94
95
  });
@@ -100,6 +101,13 @@ const MessageList = ({ navigation }) => {
100
101
  (0, init_1.getImManager)().setFlatListRef(messageListRef);
101
102
  (0, init_1.getImManager)().setInputRef(bar);
102
103
  }, []);
104
+ (0, react_1.useEffect)(() => {
105
+ var _a;
106
+ if (isSearch) {
107
+ (_a = messageListRef.current) === null || _a === void 0 ? void 0 : _a.scrollToOffset({ animated: false, offset: 0 });
108
+ (0, init_1.getImManager)().store.dispatch(im_base_1.MessageActions.setIsSearch(false));
109
+ }
110
+ }, [isSearch]);
103
111
  const onLongPressPopover = (0, react_1.useCallback)((message, nativeEvent) => {
104
112
  setNativeEvent(nativeEvent);
105
113
  setSelectMessage(message);
@@ -32,15 +32,39 @@ const rn_ui_1 = require("@smart-link/rn-ui");
32
32
  const react_1 = __importStar(require("react"));
33
33
  const react_native_1 = require("react-native");
34
34
  const MessagePayload_1 = __importDefault(require("./components/MessagePayload"));
35
+ const MessagePictureAlbum_1 = __importDefault(require("./components/MessagePictureAlbum"));
36
+ const lodash_es_1 = require("lodash-es");
35
37
  const MessageRecord = ({ navigation, route: { params } }) => {
36
- const { messages, title } = params;
38
+ const { messages, messageSeq, title } = params;
37
39
  (0, react_1.useEffect)(() => {
38
40
  navigation.setOptions({
39
41
  title,
40
42
  });
41
43
  }, [navigation, title]);
44
+ const [updateMessages, setUpdateMessages] = react_1.default.useState([]);
45
+ const [previewMessages, setPreviewMessages] = react_1.default.useState([]);
46
+ const [showAlbum, setShowAlbum] = react_1.default.useState(false);
47
+ const [targetMessageSeq, setTargetMessageSeq] = react_1.default.useState('');
48
+ (0, react_1.useEffect)(() => {
49
+ setUpdateMessages((0, lodash_es_1.cloneDeep)(messages));
50
+ }, [messages]);
51
+ const onPress = (item) => {
52
+ var _a;
53
+ // console.log('MessageRecord: ', item);
54
+ if (((_a = item.payload.quote) === null || _a === void 0 ? void 0 : _a.quoteMessage.payloadType) === 'picture') {
55
+ setShowAlbum(true);
56
+ setTargetMessageSeq(item.payload.quote.quoteMessage.messageSeq);
57
+ setPreviewMessages([item.payload.quote.quoteMessage]);
58
+ return;
59
+ }
60
+ if (item.payloadType === 'picture') {
61
+ setShowAlbum(true);
62
+ setTargetMessageSeq(item.messageSeq);
63
+ setPreviewMessages(updateMessages);
64
+ }
65
+ };
42
66
  return (<rn_ui_1.NavigationPage noPadding>
43
- <react_native_1.FlatList contentContainerStyle={styles.list} data={messages} renderItem={({ item, index }) => {
67
+ <react_native_1.FlatList contentContainerStyle={styles.list} data={updateMessages} renderItem={({ item, index }) => {
44
68
  const isSamePerson = index > 0 && messages[index - 1].messageFrom === item.messageFrom;
45
69
  return (<react_native_1.View style={styles.messageItem}>
46
70
  <react_native_1.View style={styles.avatar}>
@@ -51,9 +75,19 @@ const MessageRecord = ({ navigation, route: { params } }) => {
51
75
  <react_native_1.Text style={styles.usernameText}>{item.messageFromName}</react_native_1.Text>
52
76
  <FormatTimeText_1.default style={styles.timeText} time={item.messageTime}></FormatTimeText_1.default>
53
77
  </react_native_1.View>
54
- <MessagePayload_1.default {...item} showArrow={false}/>
78
+ <MessagePayload_1.default {...item} isRecord direction="left" showArrow={false} onPress={() => {
79
+ onPress(item);
80
+ }} onLoad={(localPath) => {
81
+ console.log('localPath: ', localPath);
82
+ if (!item.payload.localPath) {
83
+ item.payload.localPath = localPath;
84
+ }
85
+ }}/>
55
86
  </react_native_1.View>
56
87
  </react_native_1.View>);
88
+ }}/>
89
+ <MessagePictureAlbum_1.default visible={showAlbum} messages={previewMessages} messageSeq={targetMessageSeq} onClose={() => {
90
+ setShowAlbum(false);
57
91
  }}/>
58
92
  </rn_ui_1.NavigationPage>);
59
93
  };
@@ -74,7 +74,7 @@ const MessageItem = ({ isMultiple, multipleSelect, conversation, message, mine,
74
74
  },
75
75
  ]}>
76
76
  {mine && isMultiple && (<rn_ui_1.Checkbox checked={isMultipleChecked} style={[styles.multipleCheckbox]}/>)}
77
- <ChatAvatar_1.default name={message.messageFromName} id={message.messageFrom} url={message.payload.avatars} size={(0, rn_ui_1.dp)(40)}/>
77
+ <ChatAvatar_1.default name={message.messageFromName} id={message.messageFrom} size={(0, rn_ui_1.dp)(40)}/>
78
78
  <react_native_1.View style={[
79
79
  {
80
80
  alignContent: 'flex-end',
@@ -7,8 +7,10 @@ export interface MessagePayloadProps extends IMessage {
7
7
  style?: StyleProp<ViewStyle>;
8
8
  direction?: 'left' | 'right';
9
9
  showArrow?: boolean;
10
+ isRecord?: boolean;
10
11
  onPress?: (e: GestureResponderEvent) => void;
11
12
  onLongPress?: (e: GestureResponderEvent) => void;
13
+ onLoad?: (localPath: string) => void;
12
14
  }
13
15
  declare const _default: React.NamedExoticComponent<MessagePayloadProps>;
14
16
  export default _default;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { PayloadProps } from './type';
3
- declare const _default: React.MemoExoticComponent<({ payload, messageSeq, direction, showArrow, messageStatus, sendSize, style, onLongPress }: PayloadProps) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ payload, messageSeq, direction, showArrow, isRecord, messageStatus, sendSize, style, onLongPress }: PayloadProps) => React.JSX.Element>;
4
4
  export default _default;
@@ -46,7 +46,7 @@ const init_1 = require("../../../../init");
46
46
  const PayloadWrapper_1 = __importDefault(require("./PayloadWrapper"));
47
47
  const file_icon_1 = require("../../../../utils/file-icon");
48
48
  const useTranslation_1 = __importDefault(require("../../../../hooks/useTranslation"));
49
- const PayloadFile = ({ payload, messageSeq, direction, showArrow = true, messageStatus, sendSize, style, onLongPress }) => {
49
+ const PayloadFile = ({ payload, messageSeq, direction, showArrow = true, isRecord, messageStatus, sendSize, style, onLongPress }) => {
50
50
  const ext = payload.filename.split('.').pop();
51
51
  const Icon = (0, file_icon_1.findSvgIcon)(ext);
52
52
  const path = (0, react_1.useRef)('');
@@ -64,15 +64,10 @@ const PayloadFile = ({ payload, messageSeq, direction, showArrow = true, message
64
64
  rn_ui_1.Toast.warning(t('fileOpenFail'));
65
65
  }
66
66
  });
67
- return (<PayloadWrapper_1.default direction={direction} showArrow={showArrow} onLongPress={onLongPress} style={[style, styles.file]} onPress={() => __awaiter(void 0, void 0, void 0, function* () {
68
- if (payload.localPath || path.current) {
69
- yield openWithLocal((payload.localPath || path.current));
70
- }
71
- else if (payload.fileId) {
72
- if (downloading.current)
73
- return;
74
- downloading.current = true;
75
- const imManager = (0, init_1.getImManager)();
67
+ const pressFile = () => __awaiter(void 0, void 0, void 0, function* () {
68
+ const imManager = (0, init_1.getImManager)();
69
+ const download = () => __awaiter(void 0, void 0, void 0, function* () {
70
+ try {
76
71
  const localPath = yield imManager.download({
77
72
  fileId: payload.fileId,
78
73
  resourceType: 'file',
@@ -90,13 +85,49 @@ const PayloadFile = ({ payload, messageSeq, direction, showArrow = true, message
90
85
  status: 'done',
91
86
  });
92
87
  path.current = localPath;
93
- (0, init_1.getImManager)().db.updateMessage({
94
- messageSeq,
95
- payload: Object.assign(Object.assign({}, payload), { localPath: localPath }),
88
+ return localPath;
89
+ }
90
+ catch (e) {
91
+ rn_ui_1.Toast.error(t('downloadError'));
92
+ setDownload({
93
+ progress: 0,
94
+ status: 'pending',
96
95
  });
96
+ throw e;
97
+ }
98
+ });
99
+ if (isRecord) {
100
+ // 聊天记录中的文件
101
+ // 需要从缓存中获取
102
+ let localPath = yield imManager.loadResourceFromCache(payload.fileId);
103
+ if (localPath) {
97
104
  yield openWithLocal(localPath);
105
+ return;
98
106
  }
99
- })}>
107
+ if (downloading.current)
108
+ return;
109
+ downloading.current = true;
110
+ localPath = yield download();
111
+ imManager.updateResource({ url: payload.fileId, localPath });
112
+ yield openWithLocal(localPath);
113
+ return;
114
+ }
115
+ if (payload.localPath || path.current) {
116
+ yield openWithLocal((payload.localPath || path.current));
117
+ }
118
+ else if (payload.fileId) {
119
+ if (downloading.current)
120
+ return;
121
+ downloading.current = true;
122
+ const localPath = yield download();
123
+ (0, init_1.getImManager)().db.updateMessage({
124
+ messageSeq,
125
+ payload: Object.assign(Object.assign({}, payload), { localPath: localPath }),
126
+ });
127
+ yield openWithLocal(localPath);
128
+ }
129
+ });
130
+ return (<PayloadWrapper_1.default direction={direction} showArrow={showArrow} onLongPress={onLongPress} style={[style, styles.file]} onPress={pressFile}>
100
131
  <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center' }}>
101
132
  <Icon style={styles.fileIcon}/>
102
133
  <react_native_1.View style={{ flex: 1 }}>
@@ -114,7 +145,7 @@ const styles = react_native_1.StyleSheet.create({
114
145
  alignItems: 'center',
115
146
  padding: (0, rn_ui_1.dp)(6),
116
147
  borderRadius: (0, rn_ui_1.dp)(8),
117
- width: react_native_1.Dimensions.get('window').width * 0.6,
148
+ width: react_native_1.Dimensions.get('window').width * 0.75,
118
149
  },
119
150
  fileIcon: {
120
151
  marginRight: (0, rn_ui_1.dp)(8),
@@ -35,7 +35,7 @@ const react_1 = __importStar(require("react"));
35
35
  const react_native_1 = require("react-native");
36
36
  const PayloadWrapper_1 = __importDefault(require("./PayloadWrapper"));
37
37
  const { width } = react_native_1.Dimensions.get('window');
38
- const PayloadMultiple = (0, react_1.memo)(({ payload, direction, showArrow = true, style, onLongPress }) => {
38
+ const PayloadMultiple = (0, react_1.memo)(({ payload, messageSeq, direction, showArrow = true, style, onLongPress }) => {
39
39
  const navigation = (0, rn_ui_1.useNavigation)();
40
40
  const { type, toName, fromName, selectedMessages } = payload;
41
41
  const { t } = (0, useTranslation_1.default)();
@@ -46,6 +46,7 @@ const PayloadMultiple = (0, react_1.memo)(({ payload, direction, showArrow = tru
46
46
  : t('multipleChatRecordTitleGroup');
47
47
  return (<PayloadWrapper_1.default direction={direction} showArrow={showArrow} style={[style, styles.wrap]} onPress={() => {
48
48
  navigation.navigate('MessageRecord', {
49
+ messageSeq,
49
50
  messages: selectedMessages,
50
51
  title,
51
52
  });
@@ -1,7 +1,4 @@
1
- import { IPayload } from '@smart-link/im-base';
2
1
  import React from 'react';
3
- type PayloadPictureProps = {
4
- payload: IPayload;
5
- };
6
- declare const _default: React.MemoExoticComponent<({ payload, ...retProps }: PayloadPictureProps) => React.JSX.Element>;
2
+ import { PayloadProps } from "./type";
3
+ declare const _default: React.MemoExoticComponent<({ payload, onLoad, ...retProps }: PayloadProps) => React.JSX.Element>;
7
4
  export default _default;
@@ -40,27 +40,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
40
40
  const react_1 = __importStar(require("react"));
41
41
  const react_native_1 = require("react-native");
42
42
  const react_native_svg_1 = require("react-native-svg");
43
- const file_1 = require("../../../../api/file");
44
43
  const golden_rectangle_1 = require("../../../../utils/golden-rectangle");
45
44
  const styles_1 = require("../../../../components/styles");
46
45
  const rn_ui_1 = require("@smart-link/rn-ui");
47
46
  const PayloadWrapper_1 = __importDefault(require("./PayloadWrapper"));
48
47
  const react_native_fast_image_1 = __importDefault(require("react-native-fast-image"));
48
+ const useDownloadSource_1 = __importDefault(require("../../../../hooks/useDownloadSource"));
49
+ const file_1 = require("../../../../utils/file");
49
50
  const { width: screenWidth } = react_native_1.Dimensions.get('window');
50
51
  const PayloadPicture = (_a) => {
51
- var { payload } = _a, retProps = __rest(_a, ["payload"]);
52
+ var { payload, onLoad } = _a, retProps = __rest(_a, ["payload", "onLoad"]);
52
53
  const ext = payload.filename.split('.').pop();
53
- const src = payload.localPath ? { uri: 'file://' + payload.localPath } : payload.fileId ? { uri: (0, file_1.getDownloadUrl)(payload.fileId) } : { uri: '' };
54
+ const localPath = (0, useDownloadSource_1.default)(payload);
55
+ (0, react_1.useEffect)(() => {
56
+ if (localPath) {
57
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(localPath);
58
+ }
59
+ }, [onLoad, localPath]);
54
60
  const size = (0, golden_rectangle_1.calculate)(payload.height || (0, rn_ui_1.dp)(163), payload.width || (0, rn_ui_1.dp)(100), 200);
55
- if (!payload.localPath && !payload.fileId) {
61
+ if (!localPath) {
56
62
  return <react_native_1.View style={[styles_1.borderStyle, size, { alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0,0,0, 0.8)' }]}/>;
57
63
  }
58
64
  let content;
59
65
  if (/svg/i.test(ext)) {
60
- content = <react_native_svg_1.SvgFromUri style={[styles_1.borderStyle]} uri={src.uri} viewBox={'0 0 1024 1024'} width={screenWidth * 0.4} height={screenWidth * 0.4}/>;
66
+ content = <react_native_svg_1.SvgFromUri style={[styles_1.borderStyle]} uri={localPath} viewBox={'0 0 1024 1024'} width={screenWidth * 0.4} height={screenWidth * 0.4}/>;
61
67
  }
62
68
  else {
63
- content = <react_native_fast_image_1.default resizeMode="cover" style={[styles_1.borderStyle, size]} source={src}/>;
69
+ content = <react_native_fast_image_1.default resizeMode="cover" style={[styles_1.borderStyle, size]} source={{
70
+ uri: (0, file_1.toAbsolutePath)(localPath),
71
+ }}/>;
64
72
  }
65
73
  return <PayloadWrapper_1.default style={styles_1.shadowStyle} {...retProps}>
66
74
  {content}
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { PayloadProps } from './type';
3
- declare const _default: React.MemoExoticComponent<({ payload, onLongPress, showArrow, direction, style }: PayloadProps) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ payload, onLongPress, onPress, isRecord, showArrow, direction, style }: PayloadProps) => React.JSX.Element>;
4
4
  export default _default;
@@ -37,7 +37,7 @@ const PayloadWrapper_1 = __importDefault(require("./PayloadWrapper"));
37
37
  const init_1 = require("../../../../init");
38
38
  const im_base_1 = require("@smart-link/im-base");
39
39
  const clipboard_1 = __importDefault(require("@react-native-clipboard/clipboard"));
40
- const PayloadText = ({ payload, onLongPress, showArrow = true, direction, style }) => {
40
+ const PayloadText = ({ payload, onLongPress, onPress, isRecord, showArrow = true, direction, style }) => {
41
41
  const { t } = (0, useTranslation_1.default)();
42
42
  const { text, quote } = payload;
43
43
  const onLongPressPhone = (phone) => {
@@ -104,6 +104,11 @@ const PayloadText = ({ payload, onLongPress, showArrow = true, direction, style
104
104
  });
105
105
  };
106
106
  const onPressQuote = (quoteMessageSeq) => {
107
+ if (isRecord) {
108
+ // @ts-ignore
109
+ onPress === null || onPress === void 0 ? void 0 : onPress();
110
+ return;
111
+ }
107
112
  const imManager = (0, init_1.getImManager)();
108
113
  imManager.store.dispatch(im_base_1.MessagePanelActions.onPressQuote(imManager, quoteMessageSeq));
109
114
  };
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { PayloadProps } from './type';
3
- declare const _default: React.MemoExoticComponent<({ messageStatus, messageSeq, payload, sendSize, onLongPress }: PayloadProps) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ messageStatus, messageSeq, payload, sendSize, isRecord, onLongPress }: PayloadProps) => React.JSX.Element>;
4
4
  export default _default;
@@ -39,16 +39,16 @@ const UploadProgress_1 = __importDefault(require("../UploadProgress"));
39
39
  const PayloadWrapper_1 = __importDefault(require("./PayloadWrapper"));
40
40
  const init_1 = require("../../../../init");
41
41
  const react_native_fast_image_1 = __importDefault(require("react-native-fast-image"));
42
- const PayloadVideo = ({ messageStatus, messageSeq, payload, sendSize = 0, onLongPress }) => {
42
+ const PayloadVideo = ({ messageStatus, messageSeq, payload, sendSize = 0, isRecord, onLongPress }) => {
43
43
  const { width, height } = payload;
44
44
  const size = (0, golden_rectangle_1.calculate)(height || (0, rn_ui_1.dp)(163), width || (0, rn_ui_1.dp)(100));
45
45
  const thumbnail = payload.imagePath ? { uri: 'file://' + payload.imagePath }
46
46
  : { uri: (0, file_1.getDownloadUrl)(payload.imageFileId) };
47
- console.log('payload video', payload);
48
47
  return (<PayloadWrapper_1.default style={[styles.root, styles_1.shadowStyle, styles_1.borderStyle, size]} onPress={() => {
49
48
  (0, init_1.getImManager)().store.dispatch((0, video_action_1.loadVideoPlayer)({
50
49
  messageSeq,
51
- payload
50
+ payload,
51
+ isRecord
52
52
  }));
53
53
  }} onLongPress={onLongPress}>
54
54
  {payload.imagePath || payload.imageFileId ? <react_native_fast_image_1.default style={[size, styles_1.borderStyle]} resizeMode='cover' source={thumbnail}/> : <react_native_1.View style={[size, styles_1.borderStyle, { backgroundColor: '#000' }]}/>}
@@ -4,6 +4,8 @@ export interface PayloadProps extends IMessage {
4
4
  style?: StyleProp<ViewStyle>;
5
5
  direction?: 'left' | 'right';
6
6
  showArrow?: boolean;
7
+ isRecord?: boolean;
7
8
  onPress?: (e: GestureResponderEvent) => void;
8
9
  onLongPress?: (e: GestureResponderEvent) => void;
10
+ onLoad?: (localPath: string) => void;
9
11
  }
@@ -31,7 +31,6 @@ const react_1 = __importStar(require("react"));
31
31
  const react_native_1 = require("react-native");
32
32
  const TextMixMessage_1 = __importDefault(require("./TextMixMessage"));
33
33
  const styles_1 = require("../../../components/styles");
34
- // @ts-ignore
35
34
  const AntDesign_1 = __importDefault(require("react-native-vector-icons/AntDesign"));
36
35
  const rn_ui_1 = require("@smart-link/rn-ui");
37
36
  const im_base_1 = require("@smart-link/im-base");
@@ -79,7 +79,7 @@ const OptionPanel = (0, react_1.forwardRef)((props, ref) => {
79
79
  });
80
80
  const sendFile = (data) => __awaiter(void 0, void 0, void 0, function* () {
81
81
  (0, scroll_1.scrollToBottom)();
82
- const destPath = yield (0, file_1.copyFile)(data.localPath, data.filename);
82
+ const destPath = yield (0, file_1.copyFile)(data.localPath, data.filename, 'file');
83
83
  yield (0, init_1.getImManager)().sendFileMessage(Object.assign({}, currentConversation), Object.assign(Object.assign({}, data), { localPath: destPath }));
84
84
  });
85
85
  const openAlbum = () => __awaiter(void 0, void 0, void 0, function* () {
@@ -135,7 +135,8 @@ const OptionPanel = (0, react_1.forwardRef)((props, ref) => {
135
135
  fileInfo.name = fileInfo.name + ext;
136
136
  }
137
137
  yield sendFile({
138
- localPath: fileInfo.uri,
138
+ // ios 中文名称编码了,需要解码
139
+ localPath: decodeURI(fileInfo.uri),
139
140
  filename: fileInfo.name,
140
141
  size: fileInfo.size,
141
142
  type: fileInfo.type,
@@ -53,6 +53,7 @@ export type IMPageParamList = {
53
53
  };
54
54
  OptionGroupManage: undefined;
55
55
  MessageRecord: {
56
+ messageSeq: string;
56
57
  messages: IMessage[];
57
58
  title: string;
58
59
  };
@@ -3,19 +3,19 @@ var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.onDefaultCheckedUser = exports.startSendContact = exports.resetState = exports.startAddMember = exports.startCreateGroup = exports.onSelectUser = exports.setCurrentRoot = exports.setSelectGroups = exports.setSelectUsers = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
- const initialState = {
6
+ const initialState = () => ({
7
7
  selectUsers: {},
8
8
  selectGroups: {},
9
9
  currentRoot: 'none',
10
10
  choosePurpose: 'none',
11
11
  checkMode: 'multiple',
12
- };
12
+ });
13
13
  const contactSlice = (0, toolkit_1.createSlice)({
14
14
  name: 'chat/contact',
15
15
  initialState,
16
16
  reducers: {
17
17
  resetState(state) {
18
- Object.assign(state, initialState);
18
+ Object.assign(state, initialState());
19
19
  },
20
20
  setSelectUsers(state, action) {
21
21
  state.selectUsers = action.payload;
@@ -2,4 +2,5 @@ import { AsyncAction, IPayload } from '@smart-link/im-base';
2
2
  export declare const loadVideoPlayer: (message: {
3
3
  messageSeq: string;
4
4
  payload: IPayload;
5
+ isRecord?: boolean;
5
6
  }) => AsyncAction;
@@ -17,28 +17,30 @@ const file_1 = require("../../api/file");
17
17
  const init_1 = require("../../init");
18
18
  const loadVideoPlayer = message => (dispatch) => __awaiter(void 0, void 0, void 0, function* () {
19
19
  console.log('loadVideoPlayer: ', message);
20
- const { payload, messageSeq } = message;
20
+ const { payload, messageSeq, isRecord } = message;
21
21
  const { width = (0, rn_ui_1.dp)(100), height = (0, rn_ui_1.dp)(163), localPath } = payload;
22
22
  const thumbnail = payload.imagePath
23
23
  ? { uri: 'file://' + payload.imagePath }
24
24
  : { uri: (0, file_1.getDownloadUrl)(payload.imageFileId) };
25
- if (!localPath) {
26
- dispatch((0, video_slice_1.showVideoPlayer)({
27
- videoLocalPath: '',
28
- videoImageHeight: height,
29
- videoImageWidth: width,
30
- videoImagePath: thumbnail.uri,
31
- }));
32
- const imManager = (0, init_1.getImManager)();
33
- const destPath = yield imManager.download({
25
+ const imManager = (0, init_1.getImManager)();
26
+ const download = () => __awaiter(void 0, void 0, void 0, function* () {
27
+ return yield imManager.download({
34
28
  fileId: payload.fileId,
35
29
  resourceType: 'video',
36
30
  filename: payload.filename || (payload.fileId + '.mp4'),
37
31
  onProgress(o) {
38
- console.log(o);
39
32
  dispatch((0, video_slice_1.setVideoDownloadProgress)(o.loaded / Number(o.total || payload.size)));
40
33
  },
41
34
  });
35
+ });
36
+ if (!localPath && !isRecord) {
37
+ dispatch((0, video_slice_1.showVideoPlayer)({
38
+ videoLocalPath: '',
39
+ videoImageHeight: height,
40
+ videoImageWidth: width,
41
+ videoImagePath: thumbnail.uri,
42
+ }));
43
+ const destPath = yield download();
42
44
  dispatch((0, video_slice_1.showVideoPlayer)({
43
45
  videoLocalPath: destPath,
44
46
  videoImageHeight: height,
@@ -53,6 +55,23 @@ const loadVideoPlayer = message => (dispatch) => __awaiter(void 0, void 0, void
53
55
  payload: Object.assign(Object.assign({}, payload), { localPath: destPath })
54
56
  });
55
57
  }
58
+ else if (!localPath && isRecord) {
59
+ // 下载文件,缓存资源
60
+ let destPath = yield imManager.loadResourceFromCache(payload.fileId);
61
+ if (!destPath) {
62
+ destPath = yield download();
63
+ imManager.updateResource({
64
+ url: payload.fileId,
65
+ localPath: destPath,
66
+ });
67
+ }
68
+ dispatch((0, video_slice_1.showVideoPlayer)({
69
+ videoLocalPath: destPath,
70
+ videoImageHeight: height,
71
+ videoImageWidth: width,
72
+ videoImagePath: thumbnail.uri,
73
+ }));
74
+ }
56
75
  else {
57
76
  dispatch((0, video_slice_1.showVideoPlayer)({
58
77
  videoLocalPath: localPath,
@@ -208,6 +208,7 @@ const extensions = {
208
208
  'text/css': '.css',
209
209
  'text/javascript': '.js',
210
210
  'text/xml': '.xml',
211
+ 'application/xml': '.xml',
211
212
  'text/csv': '.csv',
212
213
  'text/markdown': '.md',
213
214
  'text/calendar': '.ics',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smart-link/rn-im",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "dependencies": {
@@ -64,7 +64,7 @@
64
64
  "redux": "^4.2.1",
65
65
  "redux-thunk": "^2.4.2",
66
66
  "@smart-link/rn-ui": "^1.0.6",
67
- "@smart-link/im-base": "^1.0.21"
67
+ "@smart-link/im-base": "^1.0.23"
68
68
  },
69
69
  "files": [
70
70
  "dist/**",