stream-chat-react-native-core 9.10.2 → 9.11.0-beta.3

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 (190) hide show
  1. package/lib/commonjs/ai-components/README.md +50 -2
  2. package/lib/commonjs/ai-components/index.js +24 -0
  3. package/lib/commonjs/ai-components/index.js.map +1 -1
  4. package/lib/commonjs/ai-components/message-composer/ComposerView.js +4 -2
  5. package/lib/commonjs/ai-components/message-composer/ComposerView.js.map +1 -1
  6. package/lib/commonjs/ai-components/message-composer/SpeechToTextButton.js +4 -1
  7. package/lib/commonjs/ai-components/message-composer/SpeechToTextButton.js.map +1 -1
  8. package/lib/commonjs/ai-components/native/AIDictation.js +6 -0
  9. package/lib/commonjs/ai-components/native/AIDictation.js.map +1 -1
  10. package/lib/commonjs/ai-components/store/dictation/store.js +4 -2
  11. package/lib/commonjs/ai-components/store/dictation/store.js.map +1 -1
  12. package/lib/commonjs/ai-components/store/dictation/useDictationState.js +4 -2
  13. package/lib/commonjs/ai-components/store/dictation/useDictationState.js.map +1 -1
  14. package/lib/commonjs/ai-components/store/index.js +22 -0
  15. package/lib/commonjs/ai-components/store/index.js.map +1 -1
  16. package/lib/commonjs/ai-components/theme.js +3 -0
  17. package/lib/commonjs/ai-components/theme.js.map +1 -1
  18. package/lib/commonjs/ai-components/transcription/useDictation.js +7 -3
  19. package/lib/commonjs/ai-components/transcription/useDictation.js.map +1 -1
  20. package/lib/commonjs/ai-components/transcription/useDictationAudioLevel.js +32 -0
  21. package/lib/commonjs/ai-components/transcription/useDictationAudioLevel.js.map +1 -0
  22. package/lib/commonjs/ai-components/voice-visualization/VoiceGlow.js +79 -0
  23. package/lib/commonjs/ai-components/voice-visualization/VoiceGlow.js.map +1 -0
  24. package/lib/commonjs/ai-components/voice-visualization/VoiceVisualizationView.js +147 -0
  25. package/lib/commonjs/ai-components/voice-visualization/VoiceVisualizationView.js.map +1 -0
  26. package/lib/commonjs/ai-components/voice-visualization/VoiceWave.js +58 -0
  27. package/lib/commonjs/ai-components/voice-visualization/VoiceWave.js.map +1 -0
  28. package/lib/commonjs/ai-components/voice-visualization/bounce.js +60 -0
  29. package/lib/commonjs/ai-components/voice-visualization/bounce.js.map +1 -0
  30. package/lib/commonjs/ai-components/voice-visualization/driver.js +208 -0
  31. package/lib/commonjs/ai-components/voice-visualization/driver.js.map +1 -0
  32. package/lib/commonjs/ai-components/voice-visualization/glowShader.js +218 -0
  33. package/lib/commonjs/ai-components/voice-visualization/glowShader.js.map +1 -0
  34. package/lib/commonjs/ai-components/voice-visualization/index.js +18 -0
  35. package/lib/commonjs/ai-components/voice-visualization/index.js.map +1 -0
  36. package/lib/commonjs/ai-components/voice-visualization/math.js +70 -0
  37. package/lib/commonjs/ai-components/voice-visualization/math.js.map +1 -0
  38. package/lib/commonjs/ai-components/voice-visualization/palette.js +47 -0
  39. package/lib/commonjs/ai-components/voice-visualization/palette.js.map +1 -0
  40. package/lib/commonjs/ai-components/voice-visualization/simplex.js +77 -0
  41. package/lib/commonjs/ai-components/voice-visualization/simplex.js.map +1 -0
  42. package/lib/commonjs/ai-components/voice-visualization/styles.js +33 -0
  43. package/lib/commonjs/ai-components/voice-visualization/styles.js.map +1 -0
  44. package/lib/commonjs/ai-components/voice-visualization/types.js +4 -0
  45. package/lib/commonjs/ai-components/voice-visualization/types.js.map +1 -0
  46. package/lib/commonjs/ai-components/voice-visualization/useReduceMotion.js +28 -0
  47. package/lib/commonjs/ai-components/voice-visualization/useReduceMotion.js.map +1 -0
  48. package/lib/commonjs/ai-components/voice-visualization/useVoiceVisualization.js +129 -0
  49. package/lib/commonjs/ai-components/voice-visualization/useVoiceVisualization.js.map +1 -0
  50. package/lib/commonjs/ai-components/voice-visualization/waveGeometry.js +124 -0
  51. package/lib/commonjs/ai-components/voice-visualization/waveGeometry.js.map +1 -0
  52. package/lib/commonjs/components/MessageInput/MessageComposer.js +2 -1
  53. package/lib/commonjs/components/MessageInput/MessageComposer.js.map +1 -1
  54. package/lib/commonjs/version.json +1 -1
  55. package/lib/module/ai-components/README.md +50 -2
  56. package/lib/module/ai-components/index.js +24 -0
  57. package/lib/module/ai-components/index.js.map +1 -1
  58. package/lib/module/ai-components/message-composer/ComposerView.js +4 -2
  59. package/lib/module/ai-components/message-composer/ComposerView.js.map +1 -1
  60. package/lib/module/ai-components/message-composer/SpeechToTextButton.js +4 -1
  61. package/lib/module/ai-components/message-composer/SpeechToTextButton.js.map +1 -1
  62. package/lib/module/ai-components/native/AIDictation.js +6 -0
  63. package/lib/module/ai-components/native/AIDictation.js.map +1 -1
  64. package/lib/module/ai-components/store/dictation/store.js +4 -2
  65. package/lib/module/ai-components/store/dictation/store.js.map +1 -1
  66. package/lib/module/ai-components/store/dictation/useDictationState.js +4 -2
  67. package/lib/module/ai-components/store/dictation/useDictationState.js.map +1 -1
  68. package/lib/module/ai-components/store/index.js +22 -0
  69. package/lib/module/ai-components/store/index.js.map +1 -1
  70. package/lib/module/ai-components/theme.js +3 -0
  71. package/lib/module/ai-components/theme.js.map +1 -1
  72. package/lib/module/ai-components/transcription/useDictation.js +7 -3
  73. package/lib/module/ai-components/transcription/useDictation.js.map +1 -1
  74. package/lib/module/ai-components/transcription/useDictationAudioLevel.js +32 -0
  75. package/lib/module/ai-components/transcription/useDictationAudioLevel.js.map +1 -0
  76. package/lib/module/ai-components/voice-visualization/VoiceGlow.js +79 -0
  77. package/lib/module/ai-components/voice-visualization/VoiceGlow.js.map +1 -0
  78. package/lib/module/ai-components/voice-visualization/VoiceVisualizationView.js +147 -0
  79. package/lib/module/ai-components/voice-visualization/VoiceVisualizationView.js.map +1 -0
  80. package/lib/module/ai-components/voice-visualization/VoiceWave.js +58 -0
  81. package/lib/module/ai-components/voice-visualization/VoiceWave.js.map +1 -0
  82. package/lib/module/ai-components/voice-visualization/bounce.js +60 -0
  83. package/lib/module/ai-components/voice-visualization/bounce.js.map +1 -0
  84. package/lib/module/ai-components/voice-visualization/driver.js +208 -0
  85. package/lib/module/ai-components/voice-visualization/driver.js.map +1 -0
  86. package/lib/module/ai-components/voice-visualization/glowShader.js +218 -0
  87. package/lib/module/ai-components/voice-visualization/glowShader.js.map +1 -0
  88. package/lib/module/ai-components/voice-visualization/index.js +18 -0
  89. package/lib/module/ai-components/voice-visualization/index.js.map +1 -0
  90. package/lib/module/ai-components/voice-visualization/math.js +70 -0
  91. package/lib/module/ai-components/voice-visualization/math.js.map +1 -0
  92. package/lib/module/ai-components/voice-visualization/palette.js +47 -0
  93. package/lib/module/ai-components/voice-visualization/palette.js.map +1 -0
  94. package/lib/module/ai-components/voice-visualization/simplex.js +77 -0
  95. package/lib/module/ai-components/voice-visualization/simplex.js.map +1 -0
  96. package/lib/module/ai-components/voice-visualization/styles.js +33 -0
  97. package/lib/module/ai-components/voice-visualization/styles.js.map +1 -0
  98. package/lib/module/ai-components/voice-visualization/types.js +4 -0
  99. package/lib/module/ai-components/voice-visualization/types.js.map +1 -0
  100. package/lib/module/ai-components/voice-visualization/useReduceMotion.js +28 -0
  101. package/lib/module/ai-components/voice-visualization/useReduceMotion.js.map +1 -0
  102. package/lib/module/ai-components/voice-visualization/useVoiceVisualization.js +129 -0
  103. package/lib/module/ai-components/voice-visualization/useVoiceVisualization.js.map +1 -0
  104. package/lib/module/ai-components/voice-visualization/waveGeometry.js +124 -0
  105. package/lib/module/ai-components/voice-visualization/waveGeometry.js.map +1 -0
  106. package/lib/module/components/MessageInput/MessageComposer.js +2 -1
  107. package/lib/module/components/MessageInput/MessageComposer.js.map +1 -1
  108. package/lib/module/version.json +1 -1
  109. package/lib/typescript/ai-components/index.d.ts +3 -1
  110. package/lib/typescript/ai-components/index.d.ts.map +1 -1
  111. package/lib/typescript/ai-components/message-composer/ComposerView.d.ts.map +1 -1
  112. package/lib/typescript/ai-components/native/AIDictation.d.ts +6 -0
  113. package/lib/typescript/ai-components/native/AIDictation.d.ts.map +1 -1
  114. package/lib/typescript/ai-components/store/dictation/store.d.ts +7 -0
  115. package/lib/typescript/ai-components/store/dictation/store.d.ts.map +1 -1
  116. package/lib/typescript/ai-components/store/dictation/useDictationState.d.ts +1 -0
  117. package/lib/typescript/ai-components/store/dictation/useDictationState.d.ts.map +1 -1
  118. package/lib/typescript/ai-components/store/index.d.ts +2 -0
  119. package/lib/typescript/ai-components/store/index.d.ts.map +1 -1
  120. package/lib/typescript/ai-components/theme.d.ts +13 -0
  121. package/lib/typescript/ai-components/theme.d.ts.map +1 -1
  122. package/lib/typescript/ai-components/transcription/useDictation.d.ts +9 -1
  123. package/lib/typescript/ai-components/transcription/useDictation.d.ts.map +1 -1
  124. package/lib/typescript/ai-components/transcription/useDictationAudioLevel.d.ts +11 -0
  125. package/lib/typescript/ai-components/transcription/useDictationAudioLevel.d.ts.map +1 -0
  126. package/lib/typescript/ai-components/voice-visualization/VoiceGlow.d.ts +13 -0
  127. package/lib/typescript/ai-components/voice-visualization/VoiceGlow.d.ts.map +1 -0
  128. package/lib/typescript/ai-components/voice-visualization/VoiceVisualizationView.d.ts +26 -0
  129. package/lib/typescript/ai-components/voice-visualization/VoiceVisualizationView.d.ts.map +1 -0
  130. package/lib/typescript/ai-components/voice-visualization/VoiceWave.d.ts +13 -0
  131. package/lib/typescript/ai-components/voice-visualization/VoiceWave.d.ts.map +1 -0
  132. package/lib/typescript/ai-components/voice-visualization/bounce.d.ts +20 -0
  133. package/lib/typescript/ai-components/voice-visualization/bounce.d.ts.map +1 -0
  134. package/lib/typescript/ai-components/voice-visualization/driver.d.ts +96 -0
  135. package/lib/typescript/ai-components/voice-visualization/driver.d.ts.map +1 -0
  136. package/lib/typescript/ai-components/voice-visualization/glowShader.d.ts +7 -0
  137. package/lib/typescript/ai-components/voice-visualization/glowShader.d.ts.map +1 -0
  138. package/lib/typescript/ai-components/voice-visualization/index.d.ts +4 -0
  139. package/lib/typescript/ai-components/voice-visualization/index.d.ts.map +1 -0
  140. package/lib/typescript/ai-components/voice-visualization/math.d.ts +26 -0
  141. package/lib/typescript/ai-components/voice-visualization/math.d.ts.map +1 -0
  142. package/lib/typescript/ai-components/voice-visualization/palette.d.ts +18 -0
  143. package/lib/typescript/ai-components/voice-visualization/palette.d.ts.map +1 -0
  144. package/lib/typescript/ai-components/voice-visualization/simplex.d.ts +11 -0
  145. package/lib/typescript/ai-components/voice-visualization/simplex.d.ts.map +1 -0
  146. package/lib/typescript/ai-components/voice-visualization/styles.d.ts +24 -0
  147. package/lib/typescript/ai-components/voice-visualization/styles.d.ts.map +1 -0
  148. package/lib/typescript/ai-components/voice-visualization/types.d.ts +45 -0
  149. package/lib/typescript/ai-components/voice-visualization/types.d.ts.map +1 -0
  150. package/lib/typescript/ai-components/voice-visualization/useReduceMotion.d.ts +10 -0
  151. package/lib/typescript/ai-components/voice-visualization/useReduceMotion.d.ts.map +1 -0
  152. package/lib/typescript/ai-components/voice-visualization/useVoiceVisualization.d.ts +18 -0
  153. package/lib/typescript/ai-components/voice-visualization/useVoiceVisualization.d.ts.map +1 -0
  154. package/lib/typescript/ai-components/voice-visualization/waveGeometry.d.ts +25 -0
  155. package/lib/typescript/ai-components/voice-visualization/waveGeometry.d.ts.map +1 -0
  156. package/lib/typescript/components/MessageInput/MessageComposer.d.ts.map +1 -1
  157. package/package.json +2 -2
  158. package/src/ai-components/README.md +50 -2
  159. package/src/ai-components/__tests__/VoiceVisualization.test.tsx +208 -0
  160. package/src/ai-components/__tests__/dictation.test.tsx +58 -1
  161. package/src/ai-components/__tests__/voiceDriver.test.ts +317 -0
  162. package/src/ai-components/__tests__/voicePalette.test.ts +124 -0
  163. package/src/ai-components/index.ts +3 -1
  164. package/src/ai-components/message-composer/ComposerView.tsx +6 -3
  165. package/src/ai-components/message-composer/SpeechToTextButton.tsx +5 -2
  166. package/src/ai-components/native/AIDictation.ts +11 -0
  167. package/src/ai-components/store/dictation/store.ts +9 -0
  168. package/src/ai-components/store/dictation/useDictationState.ts +2 -1
  169. package/src/ai-components/store/index.ts +2 -0
  170. package/src/ai-components/theme.ts +16 -0
  171. package/src/ai-components/transcription/useDictation.ts +16 -3
  172. package/src/ai-components/transcription/useDictationAudioLevel.ts +38 -0
  173. package/src/ai-components/voice-visualization/VoiceGlow.tsx +79 -0
  174. package/src/ai-components/voice-visualization/VoiceVisualizationView.tsx +179 -0
  175. package/src/ai-components/voice-visualization/VoiceWave.tsx +67 -0
  176. package/src/ai-components/voice-visualization/bounce.ts +61 -0
  177. package/src/ai-components/voice-visualization/driver.ts +240 -0
  178. package/src/ai-components/voice-visualization/glowShader.ts +227 -0
  179. package/src/ai-components/voice-visualization/index.ts +3 -0
  180. package/src/ai-components/voice-visualization/math.ts +73 -0
  181. package/src/ai-components/voice-visualization/palette.ts +59 -0
  182. package/src/ai-components/voice-visualization/simplex.ts +92 -0
  183. package/src/ai-components/voice-visualization/styles.ts +42 -0
  184. package/src/ai-components/voice-visualization/types.ts +44 -0
  185. package/src/ai-components/voice-visualization/useReduceMotion.ts +34 -0
  186. package/src/ai-components/voice-visualization/useVoiceVisualization.ts +153 -0
  187. package/src/ai-components/voice-visualization/waveGeometry.ts +137 -0
  188. package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewPollLabel.test.tsx +1 -1
  189. package/src/components/MessageInput/MessageComposer.tsx +4 -2
  190. package/src/version.json +1 -1
@@ -0,0 +1,153 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useColorScheme } from 'react-native';
3
+
4
+ import {
5
+ type FrameInfo,
6
+ runOnUI,
7
+ useFrameCallback,
8
+ useSharedValue,
9
+ withTiming,
10
+ } from 'react-native-reanimated';
11
+
12
+ import {
13
+ advanceDriver,
14
+ createDriverState,
15
+ hoverDriver,
16
+ tapDriver,
17
+ type VoiceDriverInput,
18
+ } from './driver';
19
+ import { audioLevelInput, expressivityInput } from './math';
20
+ import { FALLBACK_COLOR, luminance, toHsvPalette } from './palette';
21
+ import type { VoiceVisualizationStyle } from './styles';
22
+ import type { VoiceVisualizationProps } from './types';
23
+ import { useReduceMotion } from './useReduceMotion';
24
+
25
+ import { useTheme } from '../contexts';
26
+
27
+ /** How long the visualization takes to fade in once its first frame is drawn, as on iOS. */
28
+ const FADE_IN_MS = 300;
29
+
30
+ /** Whether to draw for a dark background: the theme's backdrop when readable, else the scheme. */
31
+ const useDark = (backdropColor: string | undefined) => {
32
+ const scheme = useColorScheme();
33
+ return useMemo(() => {
34
+ const backdrop = backdropColor ? luminance(backdropColor) : null;
35
+ if (backdrop !== null) return backdrop < 0.5 ? 1 : 0;
36
+ return scheme === 'dark' ? 1 : 0;
37
+ }, [backdropColor, scheme]);
38
+ };
39
+
40
+ /**
41
+ * A voice visualization's motion, advanced once a frame on the UI thread.
42
+ *
43
+ * The driver lives in a shared value the renderers derive from, so a frame redraws without
44
+ * re-rendering React, and `audioLevel` is read in the frame callback, so a level changing many
45
+ * times a second re-renders nothing either.
46
+ */
47
+ export const useVoiceVisualization = (
48
+ { audioLevel, colors, expressivity, state }: VoiceVisualizationProps,
49
+ style: VoiceVisualizationStyle,
50
+ ) => {
51
+ const { theme } = useTheme();
52
+ const reduceMotion = useReduceMotion();
53
+ const themeColors = theme.voiceVisualization?.colors;
54
+ const dark = useDark(theme.voiceVisualization?.backdropColor);
55
+
56
+ const colorsKey = (colors ?? []).join('|');
57
+ const themeKey = (themeColors ?? []).join('|');
58
+ const palette = useMemo(() => {
59
+ const own = toHsvPalette(colors ?? []);
60
+ if (own.length) return own;
61
+ const fromTheme = toHsvPalette(themeColors ?? []);
62
+ return fromTheme.length ? fromTheme : toHsvPalette([FALLBACK_COLOR]);
63
+ // Keyed by the colors themselves, so a new array of the same colors changes nothing.
64
+ // eslint-disable-next-line react-hooks/exhaustive-deps
65
+ }, [colorsKey, themeKey]);
66
+
67
+ const input: VoiceDriverInput = {
68
+ audioLevel: null,
69
+ colors: palette,
70
+ expressivity: expressivityInput(expressivity),
71
+ reduceMotion,
72
+ state,
73
+ };
74
+
75
+ // Starts settled on the first input, so the first frame shows it rather than easing into it.
76
+ const [initialDriver] = useState(() => createDriverState(input, style.levelResponse));
77
+ const driver = useSharedValue(initialDriver);
78
+ const inputValue = useSharedValue(input);
79
+ const darkValue = useSharedValue(dark);
80
+ const opacity = useSharedValue(0);
81
+ const fadingIn = useSharedValue(false);
82
+
83
+ useEffect(() => {
84
+ inputValue.value = {
85
+ audioLevel: null,
86
+ colors: palette,
87
+ expressivity: expressivityInput(expressivity),
88
+ reduceMotion,
89
+ state,
90
+ };
91
+ }, [expressivity, inputValue, palette, reduceMotion, state]);
92
+
93
+ useEffect(() => {
94
+ darkValue.value = dark;
95
+ }, [dark, darkValue]);
96
+
97
+ const onFrame = useCallback(
98
+ (frame: FrameInfo) => {
99
+ 'worklet';
100
+ const seconds = (frame.timeSincePreviousFrame ?? 0) / 1000;
101
+ const current = inputValue.value;
102
+ const level = audioLevelInput(audioLevel ? audioLevel.value : null);
103
+ const next = level === current.audioLevel ? current : { ...current, audioLevel: level };
104
+ driver.modify((d) => {
105
+ 'worklet';
106
+ advanceDriver(d, next, seconds);
107
+ return d;
108
+ });
109
+ // It fades in once it has something to show, rather than flashing empty while the first
110
+ // frame lands.
111
+ if (!fadingIn.value) {
112
+ fadingIn.value = true;
113
+ opacity.value = withTiming(1, { duration: FADE_IN_MS });
114
+ }
115
+ },
116
+ [audioLevel, driver, fadingIn, inputValue, opacity],
117
+ );
118
+ useFrameCallback(onFrame);
119
+
120
+ /** A tap at a point centred and normalized to the shorter side, y up. */
121
+ const tap = useCallback(
122
+ (x: number, y: number) => {
123
+ runOnUI((tapX: number, tapY: number) => {
124
+ 'worklet';
125
+ driver.modify((d) => {
126
+ 'worklet';
127
+ tapDriver(d, inputValue.value, tapX, tapY);
128
+ return d;
129
+ });
130
+ })(x, y);
131
+ },
132
+ [driver, inputValue],
133
+ );
134
+
135
+ /** Where a pointer hovers, or null once it has left. */
136
+ const hover = useCallback(
137
+ (x: number | null, y: number | null) => {
138
+ runOnUI((hoverX: number | null, hoverY: number | null) => {
139
+ 'worklet';
140
+ driver.modify((d) => {
141
+ 'worklet';
142
+ hoverDriver(d, inputValue.value, hoverX, hoverY);
143
+ return d;
144
+ });
145
+ })(x, y);
146
+ },
147
+ [driver, inputValue],
148
+ );
149
+
150
+ return { dark: darkValue, driver, hover, opacity, tap };
151
+ };
152
+
153
+ export type VoiceVisualization = ReturnType<typeof useVoiceVisualization>;
@@ -0,0 +1,137 @@
1
+ import { Skia, type SkPath } from '@shopify/react-native-skia';
2
+
3
+ import { driverReact, driverScale, type VoiceDriverState } from './driver';
4
+ import { clamp, mix, saturate, smoothstep, speechEnv, vivid } from './math';
5
+
6
+ const POINTS = 160;
7
+ export const WAVE_STOPS = 13;
8
+ export const WAVE_START = -0.42;
9
+ export const WAVE_END = 0.42;
10
+
11
+ /** The stops' positions along the gradient, evenly spaced. */
12
+ export const WAVE_POSITIONS = Array.from({ length: WAVE_STOPS }, (_, s) => s / (WAVE_STOPS - 1));
13
+
14
+ const sq = (x: number) => {
15
+ 'worklet';
16
+ return x * x;
17
+ };
18
+
19
+ const bandCenter = (i: number, seg: number, t: number) => {
20
+ 'worklet';
21
+ switch (i) {
22
+ case 0:
23
+ return 0.5 * seg + 0.12 * Math.sin(t * 0.13);
24
+ case 1:
25
+ return 1.5 * seg + 0.13 * Math.sin(t * 0.11 + 2.1);
26
+ case 2:
27
+ return 2.5 * seg + 0.12 * Math.sin(t * 0.17 + 4.2);
28
+ case 3:
29
+ return 3.5 * seg + 0.12 * Math.sin(t * 0.15 + 1);
30
+ default:
31
+ return 4.5 * seg + 0.12 * Math.sin(t * 0.1 + 3.3);
32
+ }
33
+ };
34
+
35
+ /** The string's height above its centre line at each point, centred and normalized, y up. */
36
+ export const waveHeights = (d: VoiceDriverState) => {
37
+ 'worklet';
38
+ const t = d.time;
39
+ const react = driverReact(d);
40
+ const center = d.load * 0.3 * Math.sin(t * 1.3);
41
+ const freq = 24 + 26 * react + 10 * d.flow;
42
+ const speak = smoothstep(0.6, 1, react);
43
+ const drive = mix(speak * 0.26 * speechEnv(t), 0.3 * d.mic, d.voice);
44
+ const reach = 0.018 + 0.022 * react + drive + 0.14 * d.flow + 0.1 * d.load;
45
+ const tapAlive = d.tapAge < 1.5;
46
+ const hovered = d.hoverAmount > 0.001;
47
+ const xs: number[] = [];
48
+ const ys: number[] = [];
49
+ for (let i = 0; i <= POINTS; i++) {
50
+ const x = WAVE_START + ((WAVE_END - WAVE_START) * i) / POINTS;
51
+ let y = Math.exp(-sq((x - center) / 0.18)) * reach * Math.sin(x * freq - t * 5);
52
+ if (tapAlive) {
53
+ y +=
54
+ Math.exp(-sq((x - d.tapX) / 0.12)) *
55
+ Math.sin((x - d.tapX) * 40 - d.tapAge * 24) *
56
+ Math.exp(-d.tapAge * 2.6) *
57
+ 0.05;
58
+ }
59
+ if (hovered) {
60
+ y +=
61
+ Math.exp(-sq((x - d.hoverX) / 0.12)) *
62
+ Math.sin((x - d.hoverX) * 40 - t * 7) *
63
+ d.hoverAmount *
64
+ 0.04;
65
+ }
66
+ xs.push(x);
67
+ ys.push(y);
68
+ }
69
+ return { xs, ys };
70
+ };
71
+
72
+ type LegacyPath = SkPath & {
73
+ lineTo: (x: number, y: number) => void;
74
+ moveTo: (x: number, y: number) => void;
75
+ };
76
+
77
+ /**
78
+ * The wave as a path in a `width` by `height` canvas. Newer Skia versions build immutable paths with
79
+ * `PathBuilder`; earlier 2.x versions mutate `SkPath` itself.
80
+ */
81
+ export const wavePath = (d: VoiceDriverState, width: number, height: number): SkPath => {
82
+ 'worklet';
83
+ const m = Math.min(width, height);
84
+ const scale = driverScale(d);
85
+ const { xs, ys } = waveHeights(d);
86
+ const px = (i: number) => width / 2 + xs[i] * m * scale;
87
+ const py = (i: number) => height / 2 - ys[i] * m * scale;
88
+ if (Skia.PathBuilder) {
89
+ const builder = Skia.PathBuilder.Make();
90
+ builder.moveTo(px(0), py(0));
91
+ for (let i = 1; i < xs.length; i++) builder.lineTo(px(i), py(i));
92
+ return builder.build();
93
+ }
94
+ const path = Skia.Path.Make() as LegacyPath;
95
+ path.moveTo(px(0), py(0));
96
+ for (let i = 1; i < xs.length; i++) path.lineTo(px(i), py(i));
97
+ return path;
98
+ };
99
+
100
+ /**
101
+ * The string's colors at its gradient stops, as RGBA from 0 to 1: up to five bands drifting along
102
+ * it, weighed by how near their centres are, its ends fading out.
103
+ */
104
+ export const waveColors = (d: VoiceDriverState, dark: number) => {
105
+ 'worklet';
106
+ const band: number[][] = [];
107
+ for (let i = 0; i < 5; i++) {
108
+ const rgb = [0, 0, 0];
109
+ vivid(d.colors[i], dark, rgb);
110
+ band.push(rgb);
111
+ }
112
+ const seg = 1 / Math.max(d.count, 1);
113
+ const bandWidth = seg * 0.7;
114
+ const stops: Float32Array[] = [];
115
+ for (let s = 0; s < WAVE_STOPS; s++) {
116
+ const x = WAVE_START + ((WAVE_END - WAVE_START) * s) / (WAVE_STOPS - 1);
117
+ const gx = clamp(x + 0.5, 0, 1);
118
+ const color = [0, 0, 0];
119
+ let total = 1e-4;
120
+ for (let i = 0; i < 5; i++) {
121
+ const present = i === 0 ? 1 : clamp(d.count - i, 0, 1);
122
+ const weight = Math.exp(-sq((gx - bandCenter(i, seg, d.time)) / bandWidth)) * present;
123
+ for (let j = 0; j < 3; j++) color[j] += band[i][j] * weight;
124
+ total += weight;
125
+ }
126
+ for (let j = 0; j < 3; j++) color[j] /= total;
127
+ saturate(color, 1.2);
128
+ saturate(color, d.sat);
129
+ const alpha = clamp(smoothstep(0.4, 0.24, Math.abs(x)) * d.bright, 0, 1);
130
+ stops.push(new Float32Array([color[0], color[1], color[2], alpha]));
131
+ }
132
+ return stops;
133
+ };
134
+
135
+ /** The line is 0.6% of the shorter side, and never under 1.5 device pixels, as on Android and iOS. */
136
+ export const waveStrokeWidth = (width: number, height: number, pixelRatio: number) =>
137
+ Math.max(0.006 * Math.min(width, height), 1.5 / pixelRatio);
@@ -80,7 +80,7 @@ describe('useChannelPreviewPollLabel', () => {
80
80
  poll.removeVote(voteA.id, MESSAGE_ID);
81
81
  });
82
82
 
83
- expect(poll.data.latest_votes_by_option['option-a']).toEqual([]);
83
+ expect(poll.data.latest_votes_by_option['option-a']).toBeUndefined();
84
84
  expect(result.current).toBe('You voted: {{ option }}');
85
85
  });
86
86
  });
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo } from 'react';
2
- import { StyleSheet, View } from 'react-native';
2
+ import { Platform, StyleSheet, View } from 'react-native';
3
3
 
4
4
  import Animated, {
5
5
  Extrapolation,
@@ -316,7 +316,9 @@ const MessageComposerWithContext = (props: MessageComposerPropsWithContext) => {
316
316
  }));
317
317
  const { bottom } = useSafeAreaInsets();
318
318
 
319
- const BOTTOM_OFFSET = isKeyboardVisible || selectedPicker ? 16 : bottom ? bottom : 16;
319
+ const safeAreaBottomOffset = Platform.OS === 'android' ? bottom + 16 : bottom;
320
+ const BOTTOM_OFFSET =
321
+ isKeyboardVisible || selectedPicker ? 16 : bottom ? safeAreaBottomOffset : 16;
320
322
 
321
323
  const micPositionContextValue = useMemo(
322
324
  () => ({ micPositionX, micPositionY }),
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "9.10.2"
2
+ "version": "9.11.0-beta.3"
3
3
  }