kasunk99-livestream-core 0.3.26 → 0.3.27
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,KAAqD,MAAM,OAAO,CAAC;AAiB1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;
|
|
1
|
+
{"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAiB1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAoDF,eAAO,MAAM,oBAAoB,uDAkY/B,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { ActivityIndicator, Keyboard, KeyboardAvoidingView as RNKeyboardAvoiding
|
|
|
4
4
|
import { useViewerSocket } from '../hooks/useViewerSocket';
|
|
5
5
|
const CHAT_NAME_COLORS = ['#f97316', '#22c55e', '#3b82f6', '#eab308', '#ec4899', '#a855f7'];
|
|
6
6
|
const BOTTOM_SAFE = Platform.OS === 'ios' ? 28 : 10;
|
|
7
|
-
const
|
|
7
|
+
const BRAND_GREEN = '#009F68';
|
|
8
8
|
let RTCViewComponent = null;
|
|
9
9
|
try {
|
|
10
10
|
const webrtc = require('react-native-webrtc');
|
|
@@ -16,6 +16,13 @@ try {
|
|
|
16
16
|
LinearGradient = require('expo-linear-gradient').LinearGradient;
|
|
17
17
|
}
|
|
18
18
|
catch { }
|
|
19
|
+
let IoniconsComponent = null;
|
|
20
|
+
try {
|
|
21
|
+
const vi = require('@expo/vector-icons');
|
|
22
|
+
if (vi.Ionicons)
|
|
23
|
+
IoniconsComponent = vi.Ionicons;
|
|
24
|
+
}
|
|
25
|
+
catch { }
|
|
19
26
|
// Use RNKC's KeyboardAvoidingView when available — it integrates with KeyboardProvider at the
|
|
20
27
|
// app root and uses WindowInsetsCompat + measure() for accurate positioning on Android.
|
|
21
28
|
// Falls back to React Native's built-in KAV for apps without RNKC installed.
|
|
@@ -212,10 +219,12 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
|
|
|
212
219
|
// KeyboardAvoidingView is the root. It measures its own screen rect, computes the exact
|
|
213
220
|
// overlap with the system keyboard, and shrinks its content area accordingly.
|
|
214
221
|
// No manual offset formulas or layout listeners are needed.
|
|
215
|
-
_jsxs(KeyboardAvoidingView, { style: styles.container, behavior: "padding", automaticOffset: true, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: StyleSheet.absoluteFillObject, objectFit: "cover", mirror: false, pointerEvents: "none" }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: [StyleSheet.absoluteFillObject, styles.videoPlaceholder], children: [joining && _jsx(ActivityIndicator, { size: "large", color: "rgba(255,255,255,0.6)" }), !joining && error && _jsx(Text, { style: styles.placeholderError, children: error }), joined && !joining && !error && hasVideo && !remoteStream && (_jsx(ActivityIndicator, { size: "large", color: "rgba(255,255,255,0.45)" })), joined && !joining && !error && hasVideo && webrtcUnavailable && (_jsx(Text, { style: styles.placeholderHint, children: "Video needs a development build" })), joined && !joining && !error && hasVideo && consumeError && (_jsx(Text, { style: styles.placeholderError, children: consumeError }))] })), LinearGradient ? (_jsx(LinearGradient, { colors: ['rgba(0,0,0,0.70)', 'rgba(0,0,0,0.0)', 'rgba(0,0,0,0.0)', 'rgba(0,0,0,0.78)'], locations: [0, 0.28, 0.48, 1], style: StyleSheet.absoluteFillObject, pointerEvents: "none" })) : null, _jsxs(View, { style: styles.topBar, pointerEvents: "box-none", children: [_jsxs(View, { style: styles.hostRow, pointerEvents: "none", children: [_jsx(View, { style: styles.avatar, children: _jsx(Text, { style: styles.avatarLetter, children: avatarLetter }) }), _jsx(Text, { style: styles.hostName, numberOfLines: 1, children: hostLabel }), _jsx(View, { style: styles.livePill, children: _jsx(Text, { style: styles.livePillText, children: "LIVE" }) })] }), _jsxs(View, { style: styles.viewerChip, pointerEvents: "none", children: [_jsx(Text, { style: styles.viewerEye, children: "\uD83D\uDC41" }), _jsx(Text, { style: styles.viewerCount, children: viewerCount > 0 ? viewerCount.toLocaleString() : '—' })] })] }),
|
|
222
|
+
_jsxs(KeyboardAvoidingView, { style: styles.container, behavior: "padding", automaticOffset: true, children: [showVideo && RTCViewComponent && streamURL ? (_jsx(RTCViewComponent, { streamURL: streamURL, stream: displayStream, style: StyleSheet.absoluteFillObject, objectFit: "cover", mirror: false, pointerEvents: "none" }, `rtc-${trackCount}-${streamURL}`)) : (_jsxs(View, { style: [StyleSheet.absoluteFillObject, styles.videoPlaceholder], children: [joining && _jsx(ActivityIndicator, { size: "large", color: "rgba(255,255,255,0.6)" }), !joining && error && _jsx(Text, { style: styles.placeholderError, children: error }), joined && !joining && !error && hasVideo && !remoteStream && (_jsx(ActivityIndicator, { size: "large", color: "rgba(255,255,255,0.45)" })), joined && !joining && !error && hasVideo && webrtcUnavailable && (_jsx(Text, { style: styles.placeholderHint, children: "Video needs a development build" })), joined && !joining && !error && hasVideo && consumeError && (_jsx(Text, { style: styles.placeholderError, children: consumeError }))] })), LinearGradient ? (_jsx(LinearGradient, { colors: ['rgba(0,0,0,0.70)', 'rgba(0,0,0,0.0)', 'rgba(0,0,0,0.0)', 'rgba(0,0,0,0.78)'], locations: [0, 0.28, 0.48, 1], style: StyleSheet.absoluteFillObject, pointerEvents: "none" })) : null, _jsxs(View, { style: styles.topBar, pointerEvents: "box-none", children: [_jsxs(View, { style: styles.hostRow, pointerEvents: "none", children: [_jsx(View, { style: styles.avatar, children: _jsx(Text, { style: styles.avatarLetter, children: avatarLetter }) }), _jsx(Text, { style: styles.hostName, numberOfLines: 1, children: hostLabel }), _jsx(View, { style: styles.livePill, children: _jsx(Text, { style: styles.livePillText, children: "LIVE" }) })] }), _jsxs(View, { style: styles.viewerChip, pointerEvents: "none", children: [_jsx(Text, { style: styles.viewerEye, children: "\uD83D\uDC41" }), _jsx(Text, { style: styles.viewerCount, children: viewerCount > 0 ? viewerCount.toLocaleString() : '—' })] })] }), _jsx(View, { style: styles.spacer, pointerEvents: "none" }), _jsx(ScrollView, { ref: chatListRef, style: styles.chatList, contentContainerStyle: styles.chatContent, showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: "always", children: chatData.map((item) => item.displayName ? (_jsx(View, { style: styles.chatBubble, children: _jsxs(Text, { style: styles.chatLine, numberOfLines: 3, children: [_jsxs(Text, { style: [styles.chatUsername, { color: getNameColor(item.displayName) }], children: [item.displayName, ' '] }), _jsx(Text, { style: styles.chatMsg, children: item.text })] }) }, item.id)) : (_jsx(View, { style: styles.joinBubble, children: _jsx(Text, { style: styles.joinText, children: item.text }) }, item.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, onSubmitEditing: sendChat, returnKeyType: "send", submitBehavior: "submit", autoFocus: true }), _jsx(Pressable, { style: [styles.sendBtn, (!hasUnsent || !joined) && styles.sendBtnOff], onPressIn: sendChat, hitSlop: { top: 8, right: 8, bottom: 8, left: 8 }, children: IoniconsComponent
|
|
223
|
+
? _jsx(IoniconsComponent, { name: "send", size: 18, color: "#fff" })
|
|
224
|
+
: _jsx(Text, { style: styles.sendIcon, children: "\u27A4" }) })] })) : (
|
|
216
225
|
// Pill bar — tapping opens the input bar.
|
|
217
226
|
_jsxs(View, { style: styles.bottomBar, children: [_jsx(TouchableOpacity, { style: [styles.typeTouchable, hasUnsent && styles.typeTouchableFilled], onPress: () => { if (canType)
|
|
218
|
-
setIsTyping(true); }, 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, children: _jsx(Text, { style: styles.bottomIconGlyph, children: "\u263A" }) }), _jsx(TouchableOpacity, { style: styles.bottomIconBtn, activeOpacity: 0.7, children: _jsx(Text, { style: styles.bottomIconGlyph,
|
|
227
|
+
setIsTyping(true); }, 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, children: _jsx(Text, { style: styles.bottomIconGlyph, children: "\u263A" }) }), _jsx(TouchableOpacity, { style: styles.bottomIconBtn, activeOpacity: 0.7, children: _jsx(Text, { style: [styles.bottomIconGlyph, styles.heartIcon], children: "\u2665" }) })] })), 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" })] }) }))] }));
|
|
219
228
|
});
|
|
220
229
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
221
230
|
const styles = StyleSheet.create({
|
|
@@ -291,26 +300,6 @@ const styles = StyleSheet.create({
|
|
|
291
300
|
},
|
|
292
301
|
viewerEye: { fontSize: 11 },
|
|
293
302
|
viewerCount: { color: 'rgba(255,255,255,0.88)', fontSize: 12, fontWeight: '500' },
|
|
294
|
-
rightColumn: {
|
|
295
|
-
position: 'absolute',
|
|
296
|
-
right: 12,
|
|
297
|
-
bottom: BOTTOM_SAFE + BOTTOM_BAR_H + 8,
|
|
298
|
-
alignItems: 'center',
|
|
299
|
-
gap: 14,
|
|
300
|
-
},
|
|
301
|
-
actionBtn: { alignItems: 'center', gap: 5 },
|
|
302
|
-
actionCircle: {
|
|
303
|
-
width: 48,
|
|
304
|
-
height: 48,
|
|
305
|
-
borderRadius: 24,
|
|
306
|
-
backgroundColor: 'rgba(255,255,255,0.14)',
|
|
307
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
308
|
-
borderColor: 'rgba(255,255,255,0.2)',
|
|
309
|
-
alignItems: 'center',
|
|
310
|
-
justifyContent: 'center',
|
|
311
|
-
},
|
|
312
|
-
actionIcon: { fontSize: 22, color: '#fff' },
|
|
313
|
-
actionLabel: { color: 'rgba(255,255,255,0.7)', fontSize: 11, fontWeight: '500' },
|
|
314
303
|
// Flex spacer — fills remaining vertical space, pushes chat + bars to bottom
|
|
315
304
|
spacer: { flex: 1 },
|
|
316
305
|
// Chat list — normal flow block, grows upward from input bar
|
|
@@ -368,12 +357,13 @@ const styles = StyleSheet.create({
|
|
|
368
357
|
width: 40,
|
|
369
358
|
height: 40,
|
|
370
359
|
borderRadius: 20,
|
|
371
|
-
backgroundColor:
|
|
360
|
+
backgroundColor: BRAND_GREEN,
|
|
372
361
|
alignItems: 'center',
|
|
373
362
|
justifyContent: 'center',
|
|
374
363
|
},
|
|
375
364
|
sendBtnOff: { backgroundColor: 'rgba(255,255,255,0.12)' },
|
|
376
365
|
sendIcon: { color: '#fff', fontSize: 15, fontWeight: '700' },
|
|
366
|
+
heartIcon: { color: BRAND_GREEN, fontSize: 24 },
|
|
377
367
|
// Pill bar — normal flow, visible when keyboard is closed
|
|
378
368
|
bottomBar: {
|
|
379
369
|
flexDirection: 'row',
|
package/package.json
CHANGED