@buoy-gg/impersonate 7.0.41 → 7.0.43

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 (78) hide show
  1. package/README.md +12 -80
  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 -17
  12. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.web.js +1 -11
  13. package/lib/commonjs/impersonate/hooks/useAutoClearAsyncStorage.js +1 -134
  14. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.js +1 -155
  15. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.web.js +1 -20
  16. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.js +1 -188
  17. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.web.js +1 -27
  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 -350
  23. package/lib/commonjs/impersonate/utils/impersonateStore.js +1 -689
  24. package/lib/commonjs/index.js +1 -150
  25. package/lib/commonjs/preset.js +1 -232
  26. package/lib/commonjs/sync/impersonateSyncAdapter.js +1 -170
  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 -13
  37. package/lib/module/impersonate/hooks/asyncStoragePeer.web.js +1 -6
  38. package/lib/module/impersonate/hooks/useAutoClearAsyncStorage.js +1 -130
  39. package/lib/module/impersonate/hooks/useAutoClearReactQuery.js +1 -151
  40. package/lib/module/impersonate/hooks/useAutoClearReactQuery.web.js +1 -16
  41. package/lib/module/impersonate/hooks/useAutoClearRedux.js +1 -183
  42. package/lib/module/impersonate/hooks/useAutoClearRedux.web.js +1 -22
  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 -341
  48. package/lib/module/impersonate/utils/impersonateStore.js +1 -686
  49. package/lib/module/index.js +1 -117
  50. package/lib/module/preset.js +1 -216
  51. package/lib/module/sync/impersonateSyncAdapter.js +1 -162
  52. package/lib/web/index.mjs +7 -8
  53. package/package.json +3 -6
  54. package/lib/typescript/impersonate/components/DataNukeSettings.d.ts.map +0 -1
  55. package/lib/typescript/impersonate/components/ImpersonateBanner.d.ts.map +0 -1
  56. package/lib/typescript/impersonate/components/ImpersonateHistoryList.d.ts.map +0 -1
  57. package/lib/typescript/impersonate/components/ImpersonateModal.d.ts.map +0 -1
  58. package/lib/typescript/impersonate/components/ImpersonateOverlay.d.ts.map +0 -1
  59. package/lib/typescript/impersonate/components/ImpersonateStatusBar.d.ts.map +0 -1
  60. package/lib/typescript/impersonate/components/UserAvatar.d.ts.map +0 -1
  61. package/lib/typescript/impersonate/components/UserCard.d.ts.map +0 -1
  62. package/lib/typescript/impersonate/components/UserSearchView.d.ts.map +0 -1
  63. package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts.map +0 -1
  64. package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts.map +0 -1
  65. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts.map +0 -1
  66. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.d.ts.map +0 -1
  67. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts.map +0 -1
  68. package/lib/typescript/impersonate/hooks/useAutoClearRedux.d.ts.map +0 -1
  69. package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts.map +0 -1
  70. package/lib/typescript/impersonate/hooks/useImpersonate.d.ts.map +0 -1
  71. package/lib/typescript/impersonate/hooks/useImpersonateHistory.d.ts.map +0 -1
  72. package/lib/typescript/impersonate/types/index.d.ts.map +0 -1
  73. package/lib/typescript/impersonate/types/types.d.ts.map +0 -1
  74. package/lib/typescript/impersonate/utils/impersonateListener.d.ts.map +0 -1
  75. package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +0 -1
  76. package/lib/typescript/index.d.ts.map +0 -1
  77. package/lib/typescript/preset.d.ts.map +0 -1
  78. 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}});
@@ -1,17 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getAsyncStorage = getAsyncStorage;
7
- function getAsyncStorage() {
8
- try {
9
- // Dynamic require to handle cases where async-storage isn't installed
10
- // eslint-disable-next-line @typescript-eslint/no-var-requires
11
- const AsyncStorage = require("@react-native-async-storage/async-storage").default;
12
- return AsyncStorage;
13
- } catch {
14
- // @react-native-async-storage/async-storage not available
15
- return null;
16
- }
17
- }
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}}
@@ -1,11 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getAsyncStorage = getAsyncStorage;
7
- var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
8
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
- function getAsyncStorage() {
10
- return _asyncStorage.default;
11
- }
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,134 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useAsyncStorageAvailability = useAsyncStorageAvailability;
7
- exports.useAutoClearAsyncStorage = useAutoClearAsyncStorage;
8
- var _asyncStoragePeer = require("./asyncStoragePeer");
9
- var _react = require("react");
10
- /**
11
- * useAutoClearAsyncStorage Hook
12
- *
13
- * Auto-detects AsyncStorage and provides a clear function.
14
- * Follows the same pattern as useAutoClearReactQuery and useAutoClearRedux.
15
- *
16
- * This hook:
17
- * 1. Dynamically requires @react-native-async-storage/async-storage
18
- * 2. Returns a clearStorage function that removes all non-buoy keys
19
- *
20
- * IMPORTANT: This preserves all @buoy/* keys to avoid clearing our own state.
21
- */
22
-
23
- // ============================================
24
- // Types
25
- // ============================================
26
-
27
- // Flag to prevent double-firing (synchronous check)
28
- let isClearing = false;
29
- // ============================================
30
- // Safe Module Loading
31
- // ============================================
32
-
33
- /**
34
- * Safely attempt to load @react-native-async-storage/async-storage
35
- */
36
-
37
- // ============================================
38
- // Main Hook
39
- // ============================================
40
-
41
- /**
42
- * Hook to auto-detect AsyncStorage and provide clearing functionality.
43
- *
44
- * This clears all keys EXCEPT those starting with @buoy/ to preserve
45
- * our own persisted state (impersonation settings, history, etc.).
46
- *
47
- * @example
48
- * ```tsx
49
- * function MyComponent() {
50
- * const { isAvailable, clearStorage } = useAutoClearAsyncStorage();
51
- *
52
- * if (isAvailable && clearStorage) {
53
- * // Clear all app data except Buoy state
54
- * await clearStorage();
55
- * }
56
- * }
57
- * ```
58
- */
59
- function useAutoClearAsyncStorage() {
60
- const [asyncStorage, setAsyncStorage] = (0, _react.useState)(null);
61
- const [error, setError] = (0, _react.useState)(null);
62
-
63
- // Check for AsyncStorage on mount
64
- (0, _react.useEffect)(() => {
65
- const storage = (0, _asyncStoragePeer.getAsyncStorage)();
66
- if (storage) {
67
- setAsyncStorage(storage);
68
- setError(null);
69
- } else {
70
- setError("@react-native-async-storage/async-storage is not installed");
71
- }
72
- }, []);
73
-
74
- // Create the clearStorage function with guard to prevent double-firing
75
- const clearStorage = (0, _react.useCallback)(async () => {
76
- // Synchronous guard - set flag immediately before any async work
77
- if (isClearing) {
78
- return;
79
- }
80
- isClearing = true;
81
- try {
82
- if (asyncStorage) {
83
- // Get all keys
84
- const allKeys = await asyncStorage.getAllKeys();
85
-
86
- // Filter out @buoy/* keys to preserve our own state
87
- const keysToRemove = allKeys.filter(key => !key.startsWith("@buoy/") && !key.startsWith("@buoy-"));
88
- if (keysToRemove.length > 0) {
89
- await asyncStorage.multiRemove([...keysToRemove]);
90
- }
91
- }
92
- } finally {
93
- // Reset flag after a short delay to allow next legitimate call
94
- setTimeout(() => {
95
- isClearing = false;
96
- }, 100);
97
- }
98
- }, [asyncStorage]);
99
-
100
- // Memoize result
101
- const result = (0, _react.useMemo)(() => {
102
- if (!asyncStorage || error) {
103
- return {
104
- isAvailable: false,
105
- error: error || "@react-native-async-storage/async-storage is not available",
106
- clearStorage: null
107
- };
108
- }
109
- return {
110
- isAvailable: true,
111
- error: null,
112
- clearStorage
113
- };
114
- }, [asyncStorage, error, clearStorage]);
115
- return result;
116
- }
117
-
118
- /**
119
- * Lightweight check to see if AsyncStorage is available
120
- * without creating the clear function
121
- */
122
- function useAsyncStorageAvailability() {
123
- const storage = (0, _asyncStoragePeer.getAsyncStorage)();
124
- if (!storage) {
125
- return {
126
- isInstalled: false,
127
- error: "@react-native-async-storage/async-storage is not installed"
128
- };
129
- }
130
- return {
131
- isInstalled: true,
132
- error: null
133
- };
134
- }
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}}