@unif/react-native-chat 2.2.0 → 3.1.0

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 (59) hide show
  1. package/lib/module/components/Composer/Composer.js +12 -7
  2. package/lib/module/components/Composer/Composer.js.map +1 -1
  3. package/lib/module/components/Composer/ComposerIconAction.js +2 -2
  4. package/lib/module/components/Composer/ComposerIconAction.js.map +1 -1
  5. package/lib/module/components/Composer/ComposerVoiceWave.js +44 -0
  6. package/lib/module/components/Composer/ComposerVoiceWave.js.map +1 -0
  7. package/lib/module/components/Composer/constants.js +20 -1
  8. package/lib/module/components/Composer/constants.js.map +1 -1
  9. package/lib/module/components/Composer/styles.js +30 -3
  10. package/lib/module/components/Composer/styles.js.map +1 -1
  11. package/lib/module/components/Message/MarkdownContent/MarkdownContent.js +9 -3
  12. package/lib/module/components/Message/MarkdownContent/MarkdownContent.js.map +1 -1
  13. package/lib/module/components/Message/MarkdownContent/styles.js +21 -11
  14. package/lib/module/components/Message/MarkdownContent/styles.js.map +1 -1
  15. package/lib/module/components/Message/Message.js +16 -4
  16. package/lib/module/components/Message/Message.js.map +1 -1
  17. package/lib/module/components/Message/styles.js +20 -14
  18. package/lib/module/components/Message/styles.js.map +1 -1
  19. package/lib/module/components/MessageList/MessageList.js +29 -8
  20. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  21. package/lib/module/components/MessageList/styles.js +14 -4
  22. package/lib/module/components/MessageList/styles.js.map +1 -1
  23. package/lib/typescript/src/components/Composer/Composer.d.ts.map +1 -1
  24. package/lib/typescript/src/components/Composer/ComposerIconAction.d.ts.map +1 -1
  25. package/lib/typescript/src/components/Composer/ComposerVoiceWave.d.ts +2 -0
  26. package/lib/typescript/src/components/Composer/ComposerVoiceWave.d.ts.map +1 -0
  27. package/lib/typescript/src/components/Composer/constants.d.ts +29 -0
  28. package/lib/typescript/src/components/Composer/constants.d.ts.map +1 -1
  29. package/lib/typescript/src/components/Composer/styles.d.ts +27 -0
  30. package/lib/typescript/src/components/Composer/styles.d.ts.map +1 -1
  31. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownContent.d.ts +1 -1
  32. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownContent.d.ts.map +1 -1
  33. package/lib/typescript/src/components/Message/MarkdownContent/styles.d.ts +104 -0
  34. package/lib/typescript/src/components/Message/MarkdownContent/styles.d.ts.map +1 -1
  35. package/lib/typescript/src/components/Message/MarkdownContent/types.d.ts +1 -0
  36. package/lib/typescript/src/components/Message/MarkdownContent/types.d.ts.map +1 -1
  37. package/lib/typescript/src/components/Message/Message.d.ts.map +1 -1
  38. package/lib/typescript/src/components/Message/styles.d.ts +11 -5
  39. package/lib/typescript/src/components/Message/styles.d.ts.map +1 -1
  40. package/lib/typescript/src/components/MessageList/MessageList.d.ts +1 -1
  41. package/lib/typescript/src/components/MessageList/MessageList.d.ts.map +1 -1
  42. package/lib/typescript/src/components/MessageList/styles.d.ts +26 -1
  43. package/lib/typescript/src/components/MessageList/styles.d.ts.map +1 -1
  44. package/lib/typescript/src/components/MessageList/types.d.ts +6 -2
  45. package/lib/typescript/src/components/MessageList/types.d.ts.map +1 -1
  46. package/package.json +4 -4
  47. package/src/components/Composer/Composer.tsx +21 -14
  48. package/src/components/Composer/ComposerIconAction.tsx +6 -1
  49. package/src/components/Composer/ComposerVoiceWave.tsx +67 -0
  50. package/src/components/Composer/constants.ts +14 -1
  51. package/src/components/Composer/styles.ts +23 -2
  52. package/src/components/Message/MarkdownContent/MarkdownContent.tsx +15 -3
  53. package/src/components/Message/MarkdownContent/styles.ts +23 -11
  54. package/src/components/Message/MarkdownContent/types.ts +1 -0
  55. package/src/components/Message/Message.tsx +46 -15
  56. package/src/components/Message/styles.ts +23 -12
  57. package/src/components/MessageList/MessageList.tsx +33 -12
  58. package/src/components/MessageList/styles.ts +22 -6
  59. package/src/components/MessageList/types.ts +6 -2
@@ -2,9 +2,14 @@ import { useCallback, useImperativeHandle, useMemo, useRef } from 'react';
2
2
  import type { RefAttributes } from 'react';
3
3
  import { FlatList, View } from 'react-native';
4
4
  import type { ListRenderItemInfo } from 'react-native';
5
- import { Button } from '@unif/react-native-design';
5
+ import {
6
+ Button,
7
+ IconButton,
8
+ Spinner,
9
+ useThemedStyles,
10
+ } from '@unif/react-native-design';
6
11
  import { DEFAULT_END_THRESHOLD } from './constants';
7
- import { styles } from './styles';
12
+ import { createStyles } from './styles';
8
13
  import { useWebPrependAnchor } from './webPrependAnchor';
9
14
  import { useMessageListScroll } from './useMessageListScroll';
10
15
  import { MessageListRow } from './MessageListRow';
@@ -25,15 +30,19 @@ export function MessageList<T>({
25
30
  followOutput = 'whenAtEnd',
26
31
  endThreshold = DEFAULT_END_THRESHOLD,
27
32
  showScrollToEnd = true,
33
+ scrollToEndBusy = false,
28
34
  onAtEndChange,
29
35
  hasEarlier = false,
30
36
  loadingEarlier = false,
31
37
  onRequestEarlier,
32
38
  keyboardDismissMode = 'on-drag',
39
+ contentContainerStyle,
40
+ showsVerticalScrollIndicator = false,
33
41
  style,
34
42
  testID,
35
43
  ref,
36
44
  }: MessageListProps<T> & RefAttributes<MessageListHandle>) {
45
+ const styles = useThemedStyles(createStyles);
37
46
  const listRef = useRef<FlatList<T>>(null);
38
47
  const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]);
39
48
  const { getRowNativeID, preservingPrependRef, cancelPrependPreservation } =
@@ -97,10 +106,7 @@ export function MessageList<T>({
97
106
  () => (footer ? <View>{footer}</View> : undefined),
98
107
  [footer]
99
108
  );
100
- const listEmpty = useMemo(
101
- () => (empty ? <View>{empty}</View> : undefined),
102
- [empty]
103
- );
109
+ const listEmpty = useMemo(() => (empty ? <>{empty}</> : undefined), [empty]);
104
110
  return (
105
111
  <View style={[styles.root, style]} testID={testID}>
106
112
  <FlatList
@@ -116,6 +122,8 @@ export function MessageList<T>({
116
122
  ListEmptyComponent={listEmpty}
117
123
  maintainVisibleContentPosition={MAINTAIN_VISIBLE_POSITION}
118
124
  keyboardDismissMode={keyboardDismissMode}
125
+ contentContainerStyle={contentContainerStyle}
126
+ showsVerticalScrollIndicator={showsVerticalScrollIndicator}
119
127
  keyboardShouldPersistTaps="handled"
120
128
  scrollEventThrottle={16}
121
129
  onLayout={onLayout}
@@ -127,12 +135,25 @@ export function MessageList<T>({
127
135
  onMomentumScrollEnd={onMomentumScrollEnd}
128
136
  />
129
137
  {showScrollToEnd && items.length > 0 && !atEnd ? (
130
- <Button
131
- label="回到最新消息"
132
- variant="secondary"
133
- style={styles.returnToEnd}
134
- onPress={() => scrollToEnd()}
135
- />
138
+ <View style={styles.returnToEnd} pointerEvents="box-none">
139
+ {scrollToEndBusy ? (
140
+ <View style={styles.returnProgress} pointerEvents="none">
141
+ <Spinner size={44} thickness={2} />
142
+ </View>
143
+ ) : null}
144
+ <IconButton
145
+ icon="arrow-down"
146
+ accessibilityLabel={
147
+ scrollToEndBusy ? '回到最新消息,正在处理' : '回到最新消息'
148
+ }
149
+ variant="ghost"
150
+ size="md"
151
+ surfaceSize={36}
152
+ iconSize={18}
153
+ style={styles.returnButton}
154
+ onPress={() => scrollToEnd()}
155
+ />
156
+ </View>
136
157
  ) : null}
137
158
  </View>
138
159
  );
@@ -1,7 +1,23 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import { space } from '@unif/react-native-design';
3
- export const styles = StyleSheet.create({
4
- root: { flex: 1, minHeight: 0, minWidth: 0 },
5
- list: { flex: 1 },
6
- returnToEnd: { position: 'absolute', bottom: space[3], alignSelf: 'center' },
7
- });
2
+ import type { ColorTokens, ShadowTokens } from '@unif/react-native-design';
3
+ export const createStyles = (colors: ColorTokens, shadows: ShadowTokens) =>
4
+ StyleSheet.create({
5
+ root: { flex: 1, minHeight: 0, minWidth: 0 },
6
+ list: { flex: 1 },
7
+ returnToEnd: {
8
+ position: 'absolute',
9
+ bottom: 0,
10
+ alignSelf: 'center',
11
+ width: 44,
12
+ height: 44,
13
+ alignItems: 'center',
14
+ justifyContent: 'center',
15
+ },
16
+ returnProgress: StyleSheet.absoluteFill,
17
+ returnButton: {
18
+ alignSelf: 'center',
19
+ borderRadius: 18,
20
+ backgroundColor: colors.surface,
21
+ ...shadows.card,
22
+ },
23
+ });
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { StyleProp, ViewStyle } from 'react-native';
2
+ import type { ScrollViewProps, StyleProp, ViewStyle } from 'react-native';
3
3
 
4
4
  export interface MessageListScrollOptions {
5
5
  animated?: boolean;
@@ -20,11 +20,15 @@ export interface MessageListProps<T> {
20
20
  followOutput?: 'whenAtEnd' | 'never';
21
21
  endThreshold?: number;
22
22
  showScrollToEnd?: boolean;
23
+ /** 外部仍在生成内容时显示返回入口的进度外环,不影响滚动操作。 */
24
+ scrollToEndBusy?: boolean;
23
25
  onAtEndChange?(atEnd: boolean): void;
24
26
  hasEarlier?: boolean;
25
27
  loadingEarlier?: boolean;
26
28
  onRequestEarlier?(): void;
27
- keyboardDismissMode?: 'none' | 'on-drag';
29
+ keyboardDismissMode?: ScrollViewProps['keyboardDismissMode'];
30
+ contentContainerStyle?: StyleProp<ViewStyle>;
31
+ showsVerticalScrollIndicator?: boolean;
28
32
  style?: StyleProp<ViewStyle>;
29
33
  testID?: string;
30
34
  }