kasunk99-livestream-core 0.3.39 → 0.3.40

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.
@@ -1 +1 @@
1
- {"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkE,MAAM,OAAO,CAAC;AAmBvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAmB/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD,CAAC;AAmEF,eAAO,MAAM,oBAAoB,uDA0gB/B,CAAC"}
1
+ {"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkE,MAAM,OAAO,CAAC;AAmBvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAmB/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD,CAAC;AAmEF,eAAO,MAAM,oBAAoB,uDAsiB/B,CAAC"}
@@ -93,10 +93,23 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
93
93
  setIsTyping(false);
94
94
  setShowEmoji(true);
95
95
  }, []);
96
+ // Switches from emoji panel back to system keyboard
97
+ const switchToKeyboard = useCallback(() => {
98
+ setShowEmoji(false);
99
+ setIsTyping(true);
100
+ }, []);
101
+ // Focus TextInput programmatically when switching to keyboard mode (not emoji mode)
102
+ useEffect(() => {
103
+ if (isTyping && !showEmoji) {
104
+ const t = setTimeout(() => textInputRef.current?.focus(), 50);
105
+ return () => clearTimeout(t);
106
+ }
107
+ }, [isTyping, showEmoji]);
96
108
  const handleEmojiSelect = useCallback((emoji) => {
97
109
  const next = chatInputRef.current + emoji;
98
110
  chatInputRef.current = next;
99
111
  setChatInput(next);
112
+ // Input bar is already visible (showEmoji=true), no state change needed
100
113
  }, []);
101
114
  // Incremented every time the app returns to foreground — forces RTCView to remount,
102
115
  // which restarts the Android SurfaceView renderer that freezes during background.
@@ -128,6 +141,7 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
128
141
  if (!isActive) {
129
142
  Keyboard.dismiss();
130
143
  setIsTyping(false);
144
+ setShowEmoji(false);
131
145
  }
132
146
  }, [isActive]);
133
147
  const seededFromRoomState = useMemo(() => {
@@ -285,6 +299,8 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
285
299
  chatInputRef.current = '';
286
300
  setChatInput('');
287
301
  Keyboard.dismiss();
302
+ setShowEmoji(false);
303
+ setIsTyping(false);
288
304
  };
289
305
  const hostLabel = stream.hostDisplayName || stream.title || 'Live';
290
306
  const avatarLetter = hostLabel[0]?.toUpperCase() ?? 'L';
@@ -301,16 +317,16 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
301
317
  ],
302
318
  opacity: anim.interpolate({ inputRange: [0, 0.65, 1], outputRange: [1, 0.85, 0] }),
303
319
  },
304
- ], children: "\u2665" }, id))) }), isTyping ? (_jsxs(View, { style: styles.inputBar, children: [_jsx(TextInput, { ref: textInputRef, style: styles.textInput, value: chatInput, onChangeText: (text) => { chatInputRef.current = text; setChatInput(text); }, placeholder: "Say something...", placeholderTextColor: "rgba(255,255,255,0.40)", editable: canType, onFocus: () => setShowEmoji(false), onSubmitEditing: sendChat, returnKeyType: "send", submitBehavior: "submit", autoFocus: true }), RNGHTouchable ? (_jsx(RNGHTouchable, { onPress: sendChat, activeOpacity: 0.75, style: [styles.sendBtn, (!hasUnsent || !joined) && styles.sendBtnOff], hitSlop: { top: 8, right: 8, bottom: 8, left: 8 }, children: IoniconsComponent
320
+ ], children: "\u2665" }, id))) }), isTyping || showEmoji ? (_jsxs(View, { style: styles.inputBar, children: [_jsx(TouchableOpacity, { style: styles.emojiToggleBtn, onPress: showEmoji ? switchToKeyboard : openEmoji, activeOpacity: 0.7, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }, children: _jsx(Text, { style: [styles.bottomIconGlyph, showEmoji && styles.emojiIconActive], children: showEmoji ? '⌨' : '☺' }) }), _jsx(TextInput, { ref: textInputRef, style: styles.textInput, value: chatInput, onChangeText: (text) => { chatInputRef.current = text; setChatInput(text); }, placeholder: "Say something...", placeholderTextColor: "rgba(255,255,255,0.40)", editable: canType, onFocus: () => setShowEmoji(false), onSubmitEditing: sendChat, returnKeyType: "send", submitBehavior: "submit" }), RNGHTouchable ? (_jsx(RNGHTouchable, { onPress: sendChat, activeOpacity: 0.75, style: [styles.sendBtn, (!hasUnsent || !joined) && styles.sendBtnOff], hitSlop: { top: 8, right: 8, bottom: 8, left: 8 }, children: IoniconsComponent
305
321
  ? _jsx(IoniconsComponent, { name: "send", size: 18, color: "#fff" })
306
322
  : _jsx(Text, { style: styles.sendIcon, children: "\u27A4" }) })) : (_jsx(Pressable, { style: [styles.sendBtn, (!hasUnsent || !joined) && styles.sendBtnOff], onPressIn: sendChat, hitSlop: { top: 8, right: 8, bottom: 8, left: 8 }, children: IoniconsComponent
307
323
  ? _jsx(IoniconsComponent, { name: "send", size: 18, color: "#fff" })
308
324
  : _jsx(Text, { style: styles.sendIcon, children: "\u27A4" }) }))] })) : (
309
- // Pill bar — tapping opens the input bar.
325
+ // Pill bar — shown when neither keyboard nor emoji panel is active
310
326
  _jsxs(View, { style: styles.bottomBar, children: [_jsx(TouchableOpacity, { style: [styles.typeTouchable, hasUnsent && styles.typeTouchableFilled], onPress: () => { if (canType) {
311
327
  setShowEmoji(false);
312
328
  setIsTyping(true);
313
- } }, activeOpacity: 0.7, children: _jsx(Text, { style: [styles.typePlaceholder, hasUnsent && styles.typePlaceholderFilled], numberOfLines: 1, children: hasUnsent ? chatInput : (joined && !joining ? 'Say something...' : 'Connecting...') }) }), _jsx(TouchableOpacity, { style: styles.bottomIconBtn, activeOpacity: 0.7, onPress: openEmoji, children: _jsx(Text, { style: [styles.bottomIconGlyph, showEmoji && styles.emojiIconActive], children: "\u263A" }) }), _jsx(TouchableOpacity, { style: styles.likeBtn, onPress: handleLike, activeOpacity: 0.75, children: _jsx(Text, { style: [styles.bottomIconGlyph, styles.heartIcon], children: "\u2665" }) })] })), showEmoji && !isTyping ? (_jsx(View, { style: styles.emojiContainer, children: _jsx(ScrollView, { style: styles.emojiScroll, showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "always", children: _jsx(View, { style: styles.emojiGrid, children: EMOJIS.map((emoji, idx) => (_jsx(TouchableOpacity, { style: styles.emojiCell, onPress: () => handleEmojiSelect(emoji), activeOpacity: 0.6, children: _jsx(Text, { style: styles.emojiText, children: emoji }) }, idx))) }) }) })) : null, streamEnded && (_jsx(View, { style: styles.endedOverlay, children: _jsxs(View, { style: styles.endedCard, children: [_jsx(Text, { style: styles.endedTitle, children: "Stream ended" }), _jsx(Text, { style: styles.endedSub, children: "The host has ended this live stream" })] }) }))] }));
329
+ } }, activeOpacity: 0.7, children: _jsx(Text, { style: [styles.typePlaceholder, hasUnsent && styles.typePlaceholderFilled], numberOfLines: 1, children: hasUnsent ? chatInput : (joined && !joining ? 'Say something...' : 'Connecting...') }) }), _jsx(TouchableOpacity, { style: styles.bottomIconBtn, activeOpacity: 0.7, onPress: openEmoji, children: _jsx(Text, { style: styles.bottomIconGlyph, children: "\u263A" }) }), _jsx(TouchableOpacity, { style: styles.likeBtn, onPress: handleLike, activeOpacity: 0.75, children: _jsx(Text, { style: [styles.bottomIconGlyph, styles.heartIcon], children: "\u2665" }) })] })), showEmoji ? (_jsx(View, { style: styles.emojiContainer, children: _jsx(ScrollView, { style: styles.emojiScroll, showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "always", children: _jsx(View, { style: styles.emojiGrid, children: EMOJIS.map((emoji, idx) => (_jsx(TouchableOpacity, { style: styles.emojiCell, onPress: () => handleEmojiSelect(emoji), activeOpacity: 0.6, children: _jsx(Text, { style: styles.emojiText, children: emoji }) }, idx))) }) }) })) : null, streamEnded && (_jsx(View, { style: styles.endedOverlay, children: _jsxs(View, { style: styles.endedCard, children: [_jsx(Text, { style: styles.endedTitle, children: "Stream ended" }), _jsx(Text, { style: styles.endedSub, children: "The host has ended this live stream" })] }) }))] }));
314
330
  });
315
331
  // ─────────────────────────────────────────────────────────────────────────────
316
332
  const styles = StyleSheet.create({
@@ -513,6 +529,7 @@ const styles = StyleSheet.create({
513
529
  endedTitle: { color: '#fff', fontSize: 22, fontWeight: '700' },
514
530
  endedSub: { color: 'rgba(255,255,255,0.5)', fontSize: 14, textAlign: 'center', lineHeight: 20 },
515
531
  // ── Emoji picker ────────────────────────────────────────────────────────
532
+ emojiToggleBtn: { width: 36, height: 40, alignItems: 'center', justifyContent: 'center' },
516
533
  emojiIconActive: { color: BRAND_GREEN },
517
534
  emojiContainer: {
518
535
  height: 260,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasunk99-livestream-core",
3
- "version": "0.3.39",
3
+ "version": "0.3.40",
4
4
  "description": "Reusable livestream viewer/host module for React Native (Expo) — mediasoup + Socket.IO",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",