@buoy-gg/impersonate 7.0.40 → 7.0.42

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 (81) hide show
  1. package/README.md +12 -76
  2. package/lib/commonjs/impersonate/components/DataNukeSettings.js +8 -675
  3. package/lib/commonjs/impersonate/components/ImpersonateBanner.js +1 -221
  4. package/lib/commonjs/impersonate/components/ImpersonateHistoryList.js +1 -181
  5. package/lib/commonjs/impersonate/components/ImpersonateModal.js +1 -319
  6. package/lib/commonjs/impersonate/components/ImpersonateOverlay.js +1 -26
  7. package/lib/commonjs/impersonate/components/ImpersonateStatusBar.js +1 -130
  8. package/lib/commonjs/impersonate/components/UserAvatar.js +1 -146
  9. package/lib/commonjs/impersonate/components/UserCard.js +1 -201
  10. package/lib/commonjs/impersonate/components/UserSearchView.js +1 -227
  11. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.js +1 -0
  12. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.web.js +1 -0
  13. package/lib/commonjs/impersonate/hooks/useAutoClearAsyncStorage.js +1 -144
  14. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.js +1 -155
  15. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.web.js +1 -0
  16. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.js +1 -188
  17. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.web.js +1 -0
  18. package/lib/commonjs/impersonate/hooks/useImpersonate.js +1 -215
  19. package/lib/commonjs/impersonate/hooks/useImpersonateHistory.js +1 -56
  20. package/lib/commonjs/impersonate/types/index.js +1 -16
  21. package/lib/commonjs/impersonate/types/types.js +1 -1
  22. package/lib/commonjs/impersonate/utils/impersonateListener.js +1 -335
  23. package/lib/commonjs/impersonate/utils/impersonateStore.js +1 -675
  24. package/lib/commonjs/index.js +1 -150
  25. package/lib/commonjs/preset.js +1 -232
  26. package/lib/commonjs/sync/impersonateSyncAdapter.js +1 -161
  27. package/lib/module/impersonate/components/DataNukeSettings.js +8 -670
  28. package/lib/module/impersonate/components/ImpersonateBanner.js +1 -215
  29. package/lib/module/impersonate/components/ImpersonateHistoryList.js +1 -176
  30. package/lib/module/impersonate/components/ImpersonateModal.js +1 -314
  31. package/lib/module/impersonate/components/ImpersonateOverlay.js +1 -21
  32. package/lib/module/impersonate/components/ImpersonateStatusBar.js +1 -125
  33. package/lib/module/impersonate/components/UserAvatar.js +1 -140
  34. package/lib/module/impersonate/components/UserCard.js +1 -196
  35. package/lib/module/impersonate/components/UserSearchView.js +1 -222
  36. package/lib/module/impersonate/hooks/asyncStoragePeer.js +1 -0
  37. package/lib/module/impersonate/hooks/asyncStoragePeer.web.js +1 -0
  38. package/lib/module/impersonate/hooks/useAutoClearAsyncStorage.js +1 -140
  39. package/lib/module/impersonate/hooks/useAutoClearReactQuery.js +1 -151
  40. package/lib/module/impersonate/hooks/useAutoClearReactQuery.web.js +1 -0
  41. package/lib/module/impersonate/hooks/useAutoClearRedux.js +1 -183
  42. package/lib/module/impersonate/hooks/useAutoClearRedux.web.js +1 -0
  43. package/lib/module/impersonate/hooks/useImpersonate.js +1 -212
  44. package/lib/module/impersonate/hooks/useImpersonateHistory.js +1 -52
  45. package/lib/module/impersonate/types/index.js +1 -3
  46. package/lib/module/impersonate/types/types.js +1 -1
  47. package/lib/module/impersonate/utils/impersonateListener.js +1 -326
  48. package/lib/module/impersonate/utils/impersonateStore.js +1 -672
  49. package/lib/module/index.js +1 -117
  50. package/lib/module/preset.js +1 -216
  51. package/lib/module/sync/impersonateSyncAdapter.js +1 -153
  52. package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts +7 -0
  53. package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts +2 -0
  54. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts +3 -12
  55. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts +3 -0
  56. package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts +4 -0
  57. package/lib/typescript/impersonate/types/types.d.ts +6 -0
  58. package/lib/typescript/impersonate/utils/impersonateListener.d.ts +1 -0
  59. package/lib/web/index.mjs +10 -0
  60. package/package.json +32 -10
  61. package/lib/typescript/impersonate/components/DataNukeSettings.d.ts.map +0 -1
  62. package/lib/typescript/impersonate/components/ImpersonateBanner.d.ts.map +0 -1
  63. package/lib/typescript/impersonate/components/ImpersonateHistoryList.d.ts.map +0 -1
  64. package/lib/typescript/impersonate/components/ImpersonateModal.d.ts.map +0 -1
  65. package/lib/typescript/impersonate/components/ImpersonateOverlay.d.ts.map +0 -1
  66. package/lib/typescript/impersonate/components/ImpersonateStatusBar.d.ts.map +0 -1
  67. package/lib/typescript/impersonate/components/UserAvatar.d.ts.map +0 -1
  68. package/lib/typescript/impersonate/components/UserCard.d.ts.map +0 -1
  69. package/lib/typescript/impersonate/components/UserSearchView.d.ts.map +0 -1
  70. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts.map +0 -1
  71. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.d.ts.map +0 -1
  72. package/lib/typescript/impersonate/hooks/useAutoClearRedux.d.ts.map +0 -1
  73. package/lib/typescript/impersonate/hooks/useImpersonate.d.ts.map +0 -1
  74. package/lib/typescript/impersonate/hooks/useImpersonateHistory.d.ts.map +0 -1
  75. package/lib/typescript/impersonate/types/index.d.ts.map +0 -1
  76. package/lib/typescript/impersonate/types/types.d.ts.map +0 -1
  77. package/lib/typescript/impersonate/utils/impersonateListener.d.ts.map +0 -1
  78. package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +0 -1
  79. package/lib/typescript/index.d.ts.map +0 -1
  80. package/lib/typescript/preset.d.ts.map +0 -1
  81. package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +0 -1
@@ -1,201 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.UserCard = UserCard;
7
- var _react = _interopRequireDefault(require("react"));
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _UserAvatar = require("./UserAvatar");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- /**
14
- * UserCard Component
15
- *
16
- * Polished user card for search results and history.
17
- * Features avatar, clean typography hierarchy, and contextual actions.
18
- */
19
-
20
- function UserCard({
21
- user,
22
- isActive = false,
23
- onPress,
24
- onStop,
25
- onRemove,
26
- showRemoveButton = false,
27
- lastUsedTime,
28
- variant = "default"
29
- }) {
30
- const displayName = user.displayName || user.email || user.id;
31
- const showEmail = user.email && user.displayName;
32
- const role = typeof user.metadata?.role === "string" ? user.metadata.role : null;
33
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
34
- testID: `buoy-impersonate-user-${user.id}`,
35
- style: [styles.container, isActive && styles.activeContainer, variant === "compact" && styles.compactContainer],
36
- onPress: onPress,
37
- disabled: isActive,
38
- activeOpacity: 0.7,
39
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
40
- style: styles.avatarSection,
41
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_UserAvatar.UserAvatar, {
42
- userId: user.id,
43
- name: displayName,
44
- size: variant === "compact" ? "small" : "medium",
45
- showActiveIndicator: isActive
46
- })
47
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
48
- style: styles.content,
49
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
50
- style: styles.nameRow,
51
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
52
- style: [styles.name, isActive && styles.activeName],
53
- numberOfLines: 1,
54
- children: displayName
55
- }), role ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
56
- style: styles.roleBadge,
57
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
58
- style: styles.roleBadgeText,
59
- children: role.toUpperCase()
60
- })
61
- }) : null]
62
- }), showEmail && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
63
- style: styles.email,
64
- numberOfLines: 1,
65
- children: user.email
66
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
67
- style: styles.metadataRow,
68
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
69
- style: styles.userId,
70
- children: ["ID: ", user.id]
71
- })
72
- })]
73
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
74
- style: styles.actions,
75
- children: [isActive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PowerToggleButton, {
76
- isEnabled: true,
77
- onToggle: onStop || (() => {}),
78
- accessibilityLabel: "Stop impersonation"
79
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
80
- style: styles.actionButton,
81
- onPress: onPress,
82
- activeOpacity: 0.7,
83
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Play, {
84
- size: 14,
85
- color: _sharedUi.night.color.onAccent
86
- })
87
- }), showRemoveButton && onRemove && !isActive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
88
- style: styles.removeButton,
89
- onPress: onRemove,
90
- activeOpacity: 0.7,
91
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
92
- size: 12,
93
- color: _sharedUi.night.color.textTertiary
94
- })
95
- })]
96
- }), lastUsedTime ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
97
- style: styles.lastUsed,
98
- children: lastUsedTime
99
- }) : null]
100
- });
101
- }
102
- const styles = _reactNative.StyleSheet.create({
103
- container: {
104
- flexDirection: "row",
105
- alignItems: "center",
106
- backgroundColor: _sharedUi.night.color.surface,
107
- borderRadius: 10,
108
- borderWidth: 1,
109
- borderColor: _sharedUi.night.color.border,
110
- padding: 12,
111
- gap: 12
112
- },
113
- activeContainer: {
114
- backgroundColor: _sharedUi.buoyColors.success + "10",
115
- borderColor: _sharedUi.buoyColors.success + "40"
116
- },
117
- compactContainer: {
118
- padding: 10,
119
- gap: 10
120
- },
121
- avatarSection: {
122
- flexShrink: 0
123
- },
124
- content: {
125
- flex: 1,
126
- minWidth: 0
127
- },
128
- nameRow: {
129
- flexDirection: "row",
130
- alignItems: "center",
131
- gap: 8,
132
- marginBottom: 2
133
- },
134
- name: {
135
- fontSize: 15,
136
- fontWeight: "600",
137
- color: _sharedUi.night.color.text,
138
- flexShrink: 1
139
- },
140
- activeName: {
141
- color: _sharedUi.buoyColors.success
142
- },
143
- roleBadge: {
144
- backgroundColor: _sharedUi.night.color.surfaceElevated,
145
- paddingHorizontal: 6,
146
- paddingVertical: 2,
147
- borderRadius: 4
148
- },
149
- roleBadgeText: {
150
- fontSize: 9,
151
- fontWeight: "700",
152
- color: _sharedUi.night.color.textTertiary,
153
- letterSpacing: 0.5
154
- },
155
- email: {
156
- fontSize: 13,
157
- color: _sharedUi.night.color.textSecondary,
158
- marginBottom: 4
159
- },
160
- metadataRow: {
161
- flexDirection: "row",
162
- alignItems: "center",
163
- gap: 4
164
- },
165
- userId: {
166
- fontSize: 11,
167
- color: _sharedUi.night.color.textTertiary,
168
- fontFamily: _sharedUi.monoFont
169
- },
170
- lastUsed: {
171
- position: "absolute",
172
- bottom: 8,
173
- right: 10,
174
- fontSize: 10,
175
- color: _sharedUi.night.color.textTertiary
176
- },
177
- actions: {
178
- flexDirection: "row",
179
- alignItems: "center",
180
- gap: 8,
181
- flexShrink: 0
182
- },
183
- actionButton: {
184
- width: 36,
185
- height: 36,
186
- borderRadius: 8,
187
- backgroundColor: _sharedUi.night.color.accent,
188
- alignItems: "center",
189
- justifyContent: "center"
190
- },
191
- removeButton: {
192
- width: 28,
193
- height: 28,
194
- borderRadius: 6,
195
- backgroundColor: _sharedUi.night.color.surfaceElevated,
196
- borderWidth: 1,
197
- borderColor: _sharedUi.night.color.border,
198
- alignItems: "center",
199
- justifyContent: "center"
200
- }
201
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.UserCard=UserCard;var _react=_interopRequireDefault(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _UserAvatar=require("./UserAvatar");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function UserCard({user:e,isActive:t=false,onPress:o,onStop:c,onRemove:r,showRemoveButton:s=false,lastUsedTime:a,variant:i="default"}){const n=e.displayName||e.email||e.id;const d=e.email&&e.displayName;const l=typeof e.metadata?.role==="string"?e.metadata.role:null;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`buoy-impersonate-user-${e.id}`,style:[styles.container,t&&styles.activeContainer,i==="compact"&&styles.compactContainer],onPress:o,disabled:t,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.avatarSection,children:(0,_jsxRuntime.jsx)(_UserAvatar.UserAvatar,{userId:e.id,name:n,size:i==="compact"?"small":"medium",showActiveIndicator:t})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.content,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.nameRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.name,t&&styles.activeName],numberOfLines:1,children:n}),l?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.roleBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.roleBadgeText,children:l.toUpperCase()})}):null]}),d&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.email,numberOfLines:1,children:e.email}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.metadataRow,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.userId,children:["ID: ",e.id]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actions,children:[t?(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:true,onToggle:c||(()=>{}),accessibilityLabel:"Stop impersonation"}):(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:o,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.Play,{size:14,color:_sharedUi.night.color.onAccent})}),s&&r&&!t&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.removeButton,onPress:r,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.night.color.textTertiary})})]}),a?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.lastUsed,children:a}):null]})}const styles=_reactNative.StyleSheet.create({container:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surface,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12,gap:12},activeContainer:{backgroundColor:_sharedUi.buoyColors.success+"10",borderColor:_sharedUi.buoyColors.success+"40"},compactContainer:{padding:10,gap:10},avatarSection:{flexShrink:0},content:{flex:1,minWidth:0},nameRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:2},name:{fontSize:15,fontWeight:"600",color:_sharedUi.night.color.text,flexShrink:1},activeName:{color:_sharedUi.buoyColors.success},roleBadge:{backgroundColor:_sharedUi.night.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},roleBadgeText:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.textTertiary,letterSpacing:.5},email:{fontSize:13,color:_sharedUi.night.color.textSecondary,marginBottom:4},metadataRow:{flexDirection:"row",alignItems:"center",gap:4},userId:{fontSize:11,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},lastUsed:{position:"absolute",bottom:8,right:10,fontSize:10,color:_sharedUi.night.color.textTertiary},actions:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:0},actionButton:{width:36,height:36,borderRadius:8,backgroundColor:_sharedUi.night.color.accent,alignItems:"center",justifyContent:"center"},removeButton:{width:28,height:28,borderRadius:6,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"}});
@@ -1,227 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.UserSearchView = UserSearchView;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _UserCard = require("./UserCard");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
- /**
14
- * UserSearchView Component
15
- *
16
- * Displays search results for user impersonation.
17
- * Search input is handled by the parent modal's header.
18
- * Uses polished UserCard component for results.
19
- */
20
-
21
- function UserSearchView({
22
- currentUser,
23
- searchQuery,
24
- searchResults,
25
- isSearching,
26
- searchError,
27
- onSelectUser,
28
- onStopImpersonation,
29
- searchAvailable = true
30
- }) {
31
- const renderUserItem = (0, _react.useCallback)(({
32
- item
33
- }) => {
34
- const isCurrentUser = currentUser?.id === item.id;
35
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_UserCard.UserCard, {
36
- user: item,
37
- isActive: isCurrentUser,
38
- onPress: () => !isCurrentUser && onSelectUser(item),
39
- onStop: isCurrentUser ? onStopImpersonation : undefined
40
- });
41
- }, [currentUser, onSelectUser, onStopImpersonation]);
42
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
43
- style: styles.container,
44
- children: [!searchAvailable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
45
- style: styles.section,
46
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
47
- style: styles.warningCard,
48
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
49
- size: 18,
50
- color: _sharedUi.night.color.warning
51
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
52
- style: styles.warningContent,
53
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
54
- style: styles.warningTitle,
55
- children: "Search Not Available"
56
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
57
- style: styles.warningText,
58
- children: "Configure the onSearchUsers callback to enable user search."
59
- })]
60
- })]
61
- })
62
- }), isSearching && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
63
- style: styles.loadingContainer,
64
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
65
- size: "small",
66
- color: _sharedUi.night.color.accent
67
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
68
- style: styles.loadingText,
69
- children: "Searching users..."
70
- })]
71
- }), searchError ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
72
- style: styles.section,
73
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
74
- style: styles.errorCard,
75
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
76
- size: 16,
77
- color: _sharedUi.night.color.danger
78
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
79
- style: styles.errorText,
80
- children: searchError
81
- })]
82
- })
83
- }) : null, searchResults.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
84
- style: styles.resultsSection,
85
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
86
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
87
- children: "Results"
88
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge, {
89
- count: searchResults.length
90
- })]
91
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
92
- data: searchResults,
93
- keyExtractor: item => item.id,
94
- renderItem: renderUserItem,
95
- ItemSeparatorComponent: () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
96
- style: styles.separator
97
- }),
98
- contentContainerStyle: styles.listContent,
99
- showsVerticalScrollIndicator: false
100
- })]
101
- }), !!searchQuery && !isSearching && searchResults.length === 0 && !searchError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
102
- style: styles.emptyStateContainer,
103
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
104
- style: styles.emptyStateIcon,
105
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Users, {
106
- size: 28,
107
- color: _sharedUi.night.color.textTertiary
108
- })
109
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
110
- style: styles.emptyStateTitle,
111
- children: "No users found"
112
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
113
- style: styles.emptyStateDescription,
114
- children: ["No results for \"", searchQuery, "\""]
115
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
116
- style: styles.emptyStateHint,
117
- children: "Try a different search term"
118
- })]
119
- }), !searchQuery && searchResults.length === 0 && !isSearching && searchAvailable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EmptyState, {
120
- title: "Search for users",
121
- description: "Tap the search icon in the header to find users by email, name, or ID",
122
- icon: _sharedUi.Search,
123
- variant: "minimal"
124
- })]
125
- });
126
- }
127
- const styles = _reactNative.StyleSheet.create({
128
- container: {
129
- flex: 1
130
- },
131
- section: {
132
- padding: 16,
133
- paddingBottom: 8
134
- },
135
- loadingContainer: {
136
- flexDirection: "row",
137
- alignItems: "center",
138
- justifyContent: "center",
139
- gap: 10,
140
- paddingVertical: 20
141
- },
142
- loadingText: {
143
- fontSize: 13,
144
- color: _sharedUi.night.color.textSecondary
145
- },
146
- resultsSection: {
147
- flex: 1,
148
- paddingHorizontal: 16
149
- },
150
- listContent: {
151
- paddingBottom: 16
152
- },
153
- separator: {
154
- height: 8
155
- },
156
- warningCard: {
157
- flexDirection: "row",
158
- alignItems: "flex-start",
159
- gap: 12,
160
- backgroundColor: _sharedUi.night.color.warningSoft,
161
- borderRadius: 10,
162
- borderWidth: 1,
163
- borderColor: _sharedUi.night.color.warning + "25",
164
- padding: 14
165
- },
166
- warningContent: {
167
- flex: 1
168
- },
169
- warningTitle: {
170
- fontSize: 14,
171
- fontWeight: "600",
172
- color: _sharedUi.night.color.warning,
173
- marginBottom: 4
174
- },
175
- warningText: {
176
- fontSize: 13,
177
- color: _sharedUi.night.color.textSecondary,
178
- lineHeight: 18
179
- },
180
- errorCard: {
181
- flexDirection: "row",
182
- alignItems: "center",
183
- gap: 10,
184
- backgroundColor: _sharedUi.night.color.dangerSoft,
185
- borderRadius: 10,
186
- borderWidth: 1,
187
- borderColor: _sharedUi.night.color.danger + "25",
188
- padding: 12
189
- },
190
- errorText: {
191
- flex: 1,
192
- fontSize: 13,
193
- color: _sharedUi.night.color.danger
194
- },
195
- emptyStateContainer: {
196
- flex: 1,
197
- alignItems: "center",
198
- justifyContent: "center",
199
- paddingHorizontal: 32,
200
- paddingVertical: 48
201
- },
202
- emptyStateIcon: {
203
- width: 56,
204
- height: 56,
205
- borderRadius: 28,
206
- backgroundColor: _sharedUi.night.color.surfaceElevated,
207
- alignItems: "center",
208
- justifyContent: "center",
209
- marginBottom: 16
210
- },
211
- emptyStateTitle: {
212
- fontSize: 16,
213
- fontWeight: "600",
214
- color: _sharedUi.night.color.text,
215
- marginBottom: 6
216
- },
217
- emptyStateDescription: {
218
- fontSize: 14,
219
- color: _sharedUi.night.color.textSecondary,
220
- textAlign: "center",
221
- marginBottom: 8
222
- },
223
- emptyStateHint: {
224
- fontSize: 12,
225
- color: _sharedUi.night.color.textTertiary
226
- }
227
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.UserSearchView=UserSearchView;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _UserCard=require("./UserCard");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(c,a){if("function"==typeof WeakMap)var n=new WeakMap,l=new WeakMap;return(_interopRequireWildcard=function(e,s){if(!s&&e&&e.__esModule)return e;var r,i,o={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return o;if(r=s?l:n){if(r.has(e))return r.get(e);r.set(e,o)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((i=(r=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(i.get||i.set)?r(o,t,i):o[t]=e[t]);return o})(c,a)}function UserSearchView({currentUser:c,searchQuery:a,searchResults:n,isSearching:l,searchError:e,onSelectUser:s,onStopImpersonation:r,searchAvailable:i=true}){const o=(0,_react.useCallback)(({item:t})=>{const d=c?.id===t.id;return(0,_jsxRuntime.jsx)(_UserCard.UserCard,{user:t,isActive:d,onPress:()=>!d&&s(t),onStop:d?r:void 0})},[c,s,r]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[!i&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.section,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.warningCard,children:[(0,_jsxRuntime.jsx)(_sharedUi.AlertTriangle,{size:18,color:_sharedUi.night.color.warning}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.warningContent,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.warningTitle,children:"Search Not Available"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.warningText,children:"Configure the onSearchUsers callback to enable user search."})]})]})}),l&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.loadingContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.ActivityIndicator,{size:"small",color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadingText,children:"Searching users..."})]}),e?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.section,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.errorCard,children:[(0,_jsxRuntime.jsx)(_sharedUi.AlertTriangle,{size:16,color:_sharedUi.night.color.danger}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.errorText,children:e})]})}):null,n.length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.resultsSection,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"Results"}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{count:n.length})]}),(0,_jsxRuntime.jsx)(_reactNative.FlatList,{data:n,keyExtractor:t=>t.id,renderItem:o,ItemSeparatorComponent:()=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.separator}),contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:false})]}),!!a&&!l&&n.length===0&&!e&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyStateContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.emptyStateIcon,children:(0,_jsxRuntime.jsx)(_sharedUi.Users,{size:28,color:_sharedUi.night.color.textTertiary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateTitle,children:"No users found"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.emptyStateDescription,children:['No results for "',a,'"']}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateHint,children:"Try a different search term"})]}),!a&&n.length===0&&!l&&i&&(0,_jsxRuntime.jsx)(_sharedUi.EmptyState,{title:"Search for users",description:"Tap the search icon in the header to find users by email, name, or ID",icon:_sharedUi.Search,variant:"minimal"})]})}const styles=_reactNative.StyleSheet.create({container:{flex:1},section:{padding:16,paddingBottom:8},loadingContainer:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10,paddingVertical:20},loadingText:{fontSize:13,color:_sharedUi.night.color.textSecondary},resultsSection:{flex:1,paddingHorizontal:16},listContent:{paddingBottom:16},separator:{height:8},warningCard:{flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:_sharedUi.night.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.warning,marginBottom:4},warningText:{fontSize:13,color:_sharedUi.night.color.textSecondary,lineHeight:18},errorCard:{flexDirection:"row",alignItems:"center",gap:10,backgroundColor:_sharedUi.night.color.dangerSoft,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.danger+"25",padding:12},errorText:{flex:1,fontSize:13,color:_sharedUi.night.color.danger},emptyStateContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyStateIcon:{width:56,height:56,borderRadius:28,backgroundColor:_sharedUi.night.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyStateTitle:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text,marginBottom:6},emptyStateDescription:{fontSize:14,color:_sharedUi.night.color.textSecondary,textAlign:"center",marginBottom:8},emptyStateHint:{fontSize:12,color:_sharedUi.night.color.textTertiary}});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getAsyncStorage=getAsyncStorage;function getAsyncStorage(){try{const e=require("@react-native-async-storage/async-storage").default;return e}catch{return null}}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getAsyncStorage=getAsyncStorage;var _asyncStorage=_interopRequireDefault(require("@react-native-async-storage/async-storage"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getAsyncStorage(){return _asyncStorage.default}
@@ -1,144 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useAsyncStorageAvailability = useAsyncStorageAvailability;
7
- exports.useAutoClearAsyncStorage = useAutoClearAsyncStorage;
8
- var _react = require("react");
9
- /**
10
- * useAutoClearAsyncStorage Hook
11
- *
12
- * Auto-detects AsyncStorage and provides a clear function.
13
- * Follows the same pattern as useAutoClearReactQuery and useAutoClearRedux.
14
- *
15
- * This hook:
16
- * 1. Dynamically requires @react-native-async-storage/async-storage
17
- * 2. Returns a clearStorage function that removes all non-buoy keys
18
- *
19
- * IMPORTANT: This preserves all @buoy/* keys to avoid clearing our own state.
20
- */
21
-
22
- // ============================================
23
- // Types
24
- // ============================================
25
-
26
- // Flag to prevent double-firing (synchronous check)
27
- let isClearing = false;
28
- // ============================================
29
- // Safe Module Loading
30
- // ============================================
31
-
32
- /**
33
- * Safely attempt to load @react-native-async-storage/async-storage
34
- */
35
- function getAsyncStorage() {
36
- try {
37
- // Dynamic require to handle cases where async-storage isn't installed
38
- // eslint-disable-next-line @typescript-eslint/no-var-requires
39
- const AsyncStorage = require("@react-native-async-storage/async-storage").default;
40
- return AsyncStorage;
41
- } catch {
42
- // @react-native-async-storage/async-storage not available
43
- return null;
44
- }
45
- }
46
-
47
- // ============================================
48
- // Main Hook
49
- // ============================================
50
-
51
- /**
52
- * Hook to auto-detect AsyncStorage and provide clearing functionality.
53
- *
54
- * This clears all keys EXCEPT those starting with @buoy/ to preserve
55
- * our own persisted state (impersonation settings, history, etc.).
56
- *
57
- * @example
58
- * ```tsx
59
- * function MyComponent() {
60
- * const { isAvailable, clearStorage } = useAutoClearAsyncStorage();
61
- *
62
- * if (isAvailable && clearStorage) {
63
- * // Clear all app data except Buoy state
64
- * await clearStorage();
65
- * }
66
- * }
67
- * ```
68
- */
69
- function useAutoClearAsyncStorage() {
70
- const [asyncStorage, setAsyncStorage] = (0, _react.useState)(null);
71
- const [error, setError] = (0, _react.useState)(null);
72
-
73
- // Check for AsyncStorage on mount
74
- (0, _react.useEffect)(() => {
75
- const storage = getAsyncStorage();
76
- if (storage) {
77
- setAsyncStorage(storage);
78
- setError(null);
79
- } else {
80
- setError("@react-native-async-storage/async-storage is not installed");
81
- }
82
- }, []);
83
-
84
- // Create the clearStorage function with guard to prevent double-firing
85
- const clearStorage = (0, _react.useCallback)(async () => {
86
- // Synchronous guard - set flag immediately before any async work
87
- if (isClearing) {
88
- return;
89
- }
90
- isClearing = true;
91
- try {
92
- if (asyncStorage) {
93
- // Get all keys
94
- const allKeys = await asyncStorage.getAllKeys();
95
-
96
- // Filter out @buoy/* keys to preserve our own state
97
- const keysToRemove = allKeys.filter(key => !key.startsWith("@buoy/") && !key.startsWith("@buoy-"));
98
- if (keysToRemove.length > 0) {
99
- await asyncStorage.multiRemove([...keysToRemove]);
100
- }
101
- }
102
- } finally {
103
- // Reset flag after a short delay to allow next legitimate call
104
- setTimeout(() => {
105
- isClearing = false;
106
- }, 100);
107
- }
108
- }, [asyncStorage]);
109
-
110
- // Memoize result
111
- const result = (0, _react.useMemo)(() => {
112
- if (!asyncStorage || error) {
113
- return {
114
- isAvailable: false,
115
- error: error || "@react-native-async-storage/async-storage is not available",
116
- clearStorage: null
117
- };
118
- }
119
- return {
120
- isAvailable: true,
121
- error: null,
122
- clearStorage
123
- };
124
- }, [asyncStorage, error, clearStorage]);
125
- return result;
126
- }
127
-
128
- /**
129
- * Lightweight check to see if AsyncStorage is available
130
- * without creating the clear function
131
- */
132
- function useAsyncStorageAvailability() {
133
- const storage = getAsyncStorage();
134
- if (!storage) {
135
- return {
136
- isInstalled: false,
137
- error: "@react-native-async-storage/async-storage is not installed"
138
- };
139
- }
140
- return {
141
- isInstalled: true,
142
- error: null
143
- };
144
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useAsyncStorageAvailability=useAsyncStorageAvailability;exports.useAutoClearAsyncStorage=useAutoClearAsyncStorage;var _asyncStoragePeer=require("./asyncStoragePeer");var _react=require("react");let isClearing=false;function useAutoClearAsyncStorage(){const[e,o]=(0,_react.useState)(null);const[r,a]=(0,_react.useState)(null);(0,_react.useEffect)(()=>{const t=(0,_asyncStoragePeer.getAsyncStorage)();if(t){o(t);a(null)}else{a("@react-native-async-storage/async-storage is not installed")}},[]);const s=(0,_react.useCallback)(async()=>{if(isClearing){return}isClearing=true;try{if(e){const t=await e.getAllKeys();const l=t.filter(n=>!n.startsWith("@buoy/")&&!n.startsWith("@buoy-"));if(l.length>0){await e.multiRemove([...l])}}}finally{setTimeout(()=>{isClearing=false},100)}},[e]);const i=(0,_react.useMemo)(()=>{if(!e||r){return{isAvailable:false,error:r||"@react-native-async-storage/async-storage is not available",clearStorage:null}}return{isAvailable:true,error:null,clearStorage:s}},[e,r,s]);return i}function useAsyncStorageAvailability(){const e=(0,_asyncStoragePeer.getAsyncStorage)();if(!e){return{isInstalled:false,error:"@react-native-async-storage/async-storage is not installed"}}return{isInstalled:true,error:null}}