@akhilpulse/samadhaan-session-replay 0.2.5 → 0.2.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akhilpulse/samadhaan-session-replay",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "React Native SDK for Samadhaan Guided Support — session recording, live remote screen-share, take-control, and guided-tour overlays.",
5
5
  "main": "src/index.ts",
6
6
  "module": "src/index.ts",
@@ -30,12 +30,13 @@ import {
30
30
  UIManager,
31
31
  findNodeHandle,
32
32
  StyleSheet,
33
+ Pressable,
33
34
  } from "react-native";
34
35
  import AsyncStorage from "@react-native-async-storage/async-storage";
35
36
  import { captureRef } from "react-native-view-shot";
36
37
 
37
38
  const STORAGE_KEY = "@akhilpulse/samadhaan-session-replay/sessionId";
38
- const SDK_VERSION = "0.2.5";
39
+ const SDK_VERSION = "0.2.6";
39
40
 
40
41
  /** Default Samadhaan production endpoint. Override via `config.serverUrl` for staging. */
41
42
  export const DEFAULT_SERVER_URL = "https://samadhaan.pulseenergy.io";
@@ -412,28 +413,43 @@ export function SessionReplayProvider({ config, children }: { config: Config; ch
412
413
  />
413
414
  ))}
414
415
 
415
- {/* Guided tour consent — absolutely-positioned View, NOT <Modal> */}
416
+ {/* Guided tour consent — centered modal card with backdrop */}
416
417
  {tourActiveHere.current && tourState.phase === "consent" && (
417
- <View style={styles.consent} pointerEvents="auto">
418
- <Text style={styles.consentTitle}>{tourState.agentName || "Support"} would like to guide you</Text>
419
- <Text style={styles.consentBody}>They will see a pointer overlaid on your screen. They cannot tap for you.</Text>
420
- <View style={styles.consentRow}>
421
- <Text onPress={() => consentTour(false)} style={[styles.btn, styles.btnGhost]}>Decline</Text>
422
- <Text onPress={() => consentTour(true)} style={[styles.btn, styles.btnPrimary]}>Accept</Text>
418
+ <View style={styles.consentBackdrop} pointerEvents="auto">
419
+ <View style={styles.consentCard}>
420
+ <View style={styles.consentIconWrap}>
421
+ <View style={styles.consentIconRing} />
422
+ <View style={styles.consentIconDot} />
423
+ </View>
424
+ <Text style={styles.consentTitle}>Guided support request</Text>
425
+ <Text style={styles.consentBody}>
426
+ <Text style={styles.consentEmphasis}>{tourState.agentName || "A support agent"}</Text>
427
+ {" wants to guide you through your screen.\n\nYou'll see a pointer showing where they're pointing. They "}
428
+ <Text style={styles.consentEmphasis}>cannot tap or type for you</Text>
429
+ {" — you stay in full control."}
430
+ </Text>
431
+ <View style={styles.consentRow}>
432
+ <Pressable onPress={() => consentTour(false)} style={({ pressed }) => [styles.btn, styles.btnGhost, pressed && styles.btnPressed]}>
433
+ <Text style={styles.btnGhostText}>Not now</Text>
434
+ </Pressable>
435
+ <Pressable onPress={() => consentTour(true)} style={({ pressed }) => [styles.btn, styles.btnPrimary, pressed && styles.btnPressed]}>
436
+ <Text style={styles.btnPrimaryText}>Allow</Text>
437
+ </Pressable>
438
+ </View>
423
439
  </View>
424
440
  </View>
425
441
  )}
426
442
 
427
- {/* Guided tour active overlay — 4 thin edge strips, never centered */}
443
+ {/* Guided tour active overlay — 4 thin edge strips, end-tour button on top-right (avoids iOS Dynamic Island) */}
428
444
  {tourActiveHere.current && tourState.phase === "active" && (
429
445
  <>
430
446
  <View pointerEvents="none" style={[styles.edge, { top: 0, left: 0, right: 0, height: 4 }]} />
431
447
  <View pointerEvents="none" style={[styles.edge, { bottom: 0, left: 0, right: 0, height: 4 }]} />
432
448
  <View pointerEvents="none" style={[styles.edge, { top: 0, bottom: 0, left: 0, width: 4 }]} />
433
449
  <View pointerEvents="none" style={[styles.edge, { top: 0, bottom: 0, right: 0, width: 4 }]} />
434
- <View style={styles.endTourPill}>
435
- <Text onPress={endTourLocal} style={styles.endTourText}>End Tour</Text>
436
- </View>
450
+ <Pressable onPress={endTourLocal} style={({ pressed }) => [styles.endTourPill, pressed && styles.btnPressed]} hitSlop={8}>
451
+ <Text style={styles.endTourText}>End tour</Text>
452
+ </Pressable>
437
453
  {pointer && (
438
454
  <>
439
455
  <View pointerEvents="none" style={[styles.pointerHalo, { left: pointer.x - 24, top: pointer.y - 24 }]} />
@@ -495,25 +511,49 @@ const styles = StyleSheet.create({
495
511
  position: "absolute", width: 40, height: 40, borderRadius: 20,
496
512
  backgroundColor: "rgba(34,197,94,0.45)", borderWidth: 2, borderColor: "#22c55e",
497
513
  },
498
- consent: {
499
- position: "absolute", left: 16, right: 16, bottom: 32, padding: 16,
500
- backgroundColor: "rgba(17,24,39,0.96)", borderRadius: 12, zIndex: 9999,
514
+ consentBackdrop: {
515
+ position: "absolute", top: 0, left: 0, right: 0, bottom: 0,
516
+ backgroundColor: "rgba(0,0,0,0.55)", justifyContent: "center", alignItems: "center",
517
+ paddingHorizontal: 24, zIndex: 9999,
518
+ },
519
+ consentCard: {
520
+ width: "100%", maxWidth: 360, backgroundColor: "#ffffff", borderRadius: 20,
521
+ paddingVertical: 24, paddingHorizontal: 22, alignItems: "center",
522
+ shadowColor: "#000", shadowOpacity: 0.25, shadowRadius: 24, shadowOffset: { width: 0, height: 12 }, elevation: 12,
523
+ },
524
+ consentIconWrap: {
525
+ width: 56, height: 56, borderRadius: 28, alignItems: "center", justifyContent: "center",
526
+ backgroundColor: "rgba(239,68,68,0.12)", marginBottom: 14,
527
+ },
528
+ consentIconRing: {
529
+ position: "absolute", width: 36, height: 36, borderRadius: 18,
530
+ borderWidth: 2, borderColor: "#ef4444",
501
531
  },
502
- consentTitle: { color: "#fff", fontSize: 16, fontWeight: "600", marginBottom: 6 },
503
- consentBody: { color: "#d1d5db", fontSize: 13, marginBottom: 12 },
504
- consentRow: { flexDirection: "row", justifyContent: "flex-end", gap: 8 },
505
- btn: { paddingVertical: 8, paddingHorizontal: 14, borderRadius: 6, fontSize: 14, overflow: "hidden" },
506
- btnGhost: { color: "#9ca3af" },
507
- btnPrimary: { color: "#fff", backgroundColor: "#22c55e" },
532
+ consentIconDot: {
533
+ width: 14, height: 14, borderRadius: 7, backgroundColor: "#ef4444",
534
+ },
535
+ consentTitle: { color: "#0f172a", fontSize: 18, fontWeight: "700", marginBottom: 8, textAlign: "center" },
536
+ consentBody: { color: "#475569", fontSize: 14, lineHeight: 20, textAlign: "center", marginBottom: 20 },
537
+ consentEmphasis: { color: "#0f172a", fontWeight: "600" },
538
+ consentRow: { flexDirection: "row", justifyContent: "center", gap: 10, width: "100%" },
539
+ btn: {
540
+ flex: 1, paddingVertical: 12, paddingHorizontal: 16, borderRadius: 10,
541
+ alignItems: "center", justifyContent: "center", minHeight: 44,
542
+ },
543
+ btnPressed: { opacity: 0.7 },
544
+ btnGhost: { backgroundColor: "#f1f5f9" },
545
+ btnGhostText: { color: "#475569", fontSize: 15, fontWeight: "600" },
546
+ btnPrimary: { backgroundColor: "#22c55e" },
547
+ btnPrimaryText: { color: "#fff", fontSize: 15, fontWeight: "600" },
508
548
  edge: { position: "absolute", backgroundColor: "rgba(34,197,94,0.7)", zIndex: 9998 },
549
+ // End-tour pill: anchored to TOP-RIGHT with safe top inset (~64px) to clear iOS Dynamic Island & status bar.
509
550
  endTourPill: {
510
- position: "absolute", top: 12, alignSelf: "center", left: 0, right: 0,
511
- flexDirection: "row", justifyContent: "center", zIndex: 9999,
512
- },
513
- endTourText: {
514
- color: "#fff", backgroundColor: "rgba(17,24,39,0.92)", paddingVertical: 6, paddingHorizontal: 14,
515
- borderRadius: 999, fontSize: 13, fontWeight: "600", overflow: "hidden",
551
+ position: "absolute", top: 64, right: 12, zIndex: 9999,
552
+ backgroundColor: "rgba(17,24,39,0.92)", paddingVertical: 8, paddingHorizontal: 14,
553
+ borderRadius: 999, flexDirection: "row", alignItems: "center",
554
+ shadowColor: "#000", shadowOpacity: 0.3, shadowRadius: 6, shadowOffset: { width: 0, height: 2 }, elevation: 6,
516
555
  },
556
+ endTourText: { color: "#fff", fontSize: 13, fontWeight: "600" },
517
557
  pointer: {
518
558
  position: "absolute", width: 24, height: 24, borderRadius: 12,
519
559
  backgroundColor: "rgba(239,68,68,1)", borderWidth: 3, borderColor: "#fff",